I overload an operator twice with the same parameter list. but with different return type:
T& operator()(par_list){blablabla}
const T& operator()(par
These functions don't overload each other; they have the same signatures, and so the attempt to redefine the same function, which is an error. The return type is not part of a function's signature. To overload a function, you must declare a second function with the same name, but different parameters or const
/volatile
qualifiers - that is, qualifiers on the function, not the return type.
(They don't override each other either; overriding is what derived classes do to their base classes' virtual functions).
It's common to define a const
and a non-const
overload of a member function; the const
overload must declare the function const
, not just the return type:
T& operator()(par_list){blablabla}
const T& operator()(par_list) const {blablabla}
^^^^^
Now the first will be called if you apply ()
to a non-const
object, and the second on a const
object. For example:
Thingy nc;
Thingy const c;
nc(); // calls the first (non-const) overload
c(); // calls the second (const) overload
You can't overload a function/method based on return type. I would expect the compiler to throw an error here. What you can do is specify the method itself as a const
method, using
const T& operator()(par_list) const {blahblah}
The const
qualifier not only means this can be called on a const
receiver, but it also is used in the overload resolution. This happens because it affects the implicit *this
parameter that's passed to the method; a const
method uses a const
qualifier on *this
, and const
qualifiers are taken into account during overload resolution.
The way you define your operators, no way the compiler can decide which operator() to call. Overloading of functions (and operators) can only be done on the type of the arguments, never on the return type. And in fact, you will have an error at compilation as soon as you define the second one, the compiler considering that you are redefining the same function/operator.
However, the following is common (and probably what you have):
T& operator()(par_list){blablabla}
const T& operator()(par_list) const {blablabla}
This additional "const" after the argument list exists because you are defining non-static member functions and member functions have an implicit hidden argument: the "this" pointer to the instance of the class. The "const" keyword there indicates if this hidden pointer is to a const instance or not. This argument participates to the overloading resolution and that is in this case what the compiler use to choose which version of the operator to use.
So:
class A {
T& operator()() { ... }
const T& operator()() const { .... }
};
A a;
const A& ca(a);
a(); -> returns a T&
ca(); -> returns a const T&