简体   繁体   中英

Are there different rules regarding ADL or naming clashes with regard to overloaded operators?

I think this example best illustrates my question:

namespace N {

    class C {
    public:
        friend bool operator==(const C& c, const C& x) {
            return true;
        }
        friend bool f(const C& c, const C& x) {
            return true;
        }
    };

    class D {
    public:
        bool operator==(const D& x) {
            bool a = C{} == C{};      // this works
            return true;
        }
        bool f(const D& x) {
            bool a = f(C{}, C{});     // this does not work
            return true;
        }
    };
}

I have always viewed overloaded operators as being just like function except for the 'calling syntax' if you will. I just noticed the above difference however in ADL or name lookup rules (I don't know which one).

Can someone explain why the bool operator==(const C& c, const C& x) is found but the bool f(const C& c, const C& x) is not?

Your D::f is hiding C::f ; if you rename the latter to C::g and adjust the call then it works fine (showing that the function can be found and accessed just fine).

Your code isn't actually directly calling the operator functions, but this is done for you by the language. Consequently you're not using the name of the operator function, so no name hiding applies.

If you write operator==(C{}, C{}) (instead of C{} == C{} ), then you'll see the same behaviour as f(C{}, C{}) ( demo ).

So, when you say "I have always viewed overloaded operators as being just like function except for the 'calling syntax' if you will", you've already hit the nail on the head.


Here's some standardese for you:

[C++11: 13.5/4]: Operator functions are usually not called directly; instead they are invoked to evaluate the operators they implement (13.5.1 – 13.5.7). They can be explicitly called, however, using the operator-function-id as the name of the function in the function call syntax (5.2.2). [ Example:

 complex z = a.operator+(b); // complex z = a+b; void* p = operator new(sizeof(int)*n); 

—end example ]

[C++11: 3.3.7/4]: [..] 4) A name declared within a member function hides a declaration of the same name whose scope extends to or past the end of the member function's class. [..]

[C++11: 3/4]: A name is a use of an identifier (2.11), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4, 6.1).

(The [qualified] operator-function-id here is ::N::C::operator== .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM