问题
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 classT
. ...
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 ofX
(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