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

巧了我就是萌 提交于 2019-12-22 09:58:04

问题


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?


回答1:


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==.)



来源:https://stackoverflow.com/questions/24168137/are-there-different-rules-regarding-adl-or-naming-clashes-with-regard-to-overloa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!