Overload Resolution: How is this not ambiguous?

喜你入骨 提交于 2019-12-12 15:12:33

问题


Suppose we have this code, copied from a separate question:

namespace x 
{
    void f()
    {
    }

    class C 
    {
        void f() 
        {
            using x::f;
            f();         // <==
        }
    };
}

The name f on the indicated line unambiguously refers to x::f (at least according to both gcc and clang). Why is x::f preferred over x::C::f in this case? Shouldn't it be ambiguous as both names are visible?


回答1:


Because the using declaration brings x::f into the scope of f, which is narrower than that of C. Unqualified lookup considers the local block scope, finds a match, and stops before considering the wider class scope. There is no argument-dependent lookup since there are no function arguments, so no further scopes are considered.




回答2:


@MikeSeymour's answer is spot on; here are the relevant standard quotes (C++11, emphasis mine):

13.3.1.1.1/3:

In unqualified function calls, the name is not qualified by an -> or . operator and has the more general form of a primary-expression. The name is looked up in the context of the function call following the normal rules for name lookup in function calls (3.4). The function declarations found by that lookup constitute the set of candidate functions. Because of the rules for name lookup, the set of candidate functions consists (1) entirely of non-member functions or (2) entirely of member functions of some class T. ...

3.4.1/1:

In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.

3.4.1/8

A name used in the definition of a member function (9.3) of class X following the function's declarator-id ... shall be declared in one of the following ways:

  • before its use in the block in which it is used or in an enclosing block (6.3), or
  • shall be a member of class X or be a member of a base class of X (10.2), or
  • ...

From 3.4.1/8, we see that a declaration for the name f (such as the declaration using x::f;) in the block in which it's used is listed earlier than f as the member of class C. As per 3.4.1/1, the earlier one is chosen, so the entire lookup resolves to x::f introduced by the using declaration.




回答3:


I think that these quotes from the C++ Standard will be relevant:

From the C++ Standard (7.3.3 The using declaration)

13 Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region (3.3) also apply to using-declarations.

And (3.3.7 Class scope)

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.



来源:https://stackoverflow.com/questions/27316607/overload-resolution-how-is-this-not-ambiguous

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