C++ overload operator twice, one return non-const reference and the other const reference, what is the preference?

后端 未结 3 1703
遥遥无期
遥遥无期 2021-02-05 15:06

I overload an operator twice with the same parameter list. but with different return type:

T& operator()(par_list){blablabla}    
const T& operator()(par         


        
相关标签:
3条回答
  • 2021-02-05 15:18

    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
    
    0 讨论(0)
  • 2021-02-05 15:23

    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.

    0 讨论(0)
  • 2021-02-05 15:23

    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&
    
    0 讨论(0)
提交回复
热议问题