Overload resolution: how is it not ambiguous?
Let's assume 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 specified line is uniquely related to x::f
(at least according to gcc and clang). Why is it x::f
preferable x::C::f
in this case? Shouldn't that be ambiguous since both names are visible?
source to share
Because the declaration using
brings x::f
to the area f
that is narrower than the area C
. An unqualified search looks at the scope of the local block, finds a match, and stops before looking at the broader scope of the class. There is no argument-dependent search since there are no function arguments, so no further scopes are considered.
source to share
@MikeSeymour's answer is in place; here are the relevant standard quotes (C ++ 11, emphasis mine):
13.3.1.1.1 / 3:
In unqualified function calls, the name is not specified by the operator
->
or.
and has the more general form of the primary expression. The name is looked up in the context of a function call according to the normal rules for looking up the name in function calls (3.4). The function declarations found by this search are a set of candidate functions. Due to the rules of name lookup, the set of candidate functions consists of (1) completely non-member functions, or (2) all of the member functions of some classT
. ...
3.4.1 / 1:
In all the cases listed in 3.4.1, the search scopes look for the declaration in the order shown in each of the relevant categories; the name search ends as soon as an ad for the name is found. If the declaration is not found, the program is poorly formed.
3.4.1 / 8
The name used in the definition of the member function (9.3) of the class
X
following the declarator-id ... function is declared in one of the following ways:
- before using it in the block in which it is used or in the closing block (6.3), or
- must be a member of a class
X
or be a member of a base classX
(10.2) or- ...
From 3.4.1 / 8, we can see that the declaration for the name f
(for example, the declaration using x::f;
) in the block in which it was used is specified earlier than f
as a member of the class C
. According to 3.4.1 / 1, the previous one is selected, so all searches are allowed up to the x::f
one entered by the ad using
.
source to share
I think these quotes from the C ++ Standard would be relevant:
From C ++ standard (7.3.3. Usage declaration)
13 Since a use-declaration is a declaration, restrictions on declarations with the same name in the same declarative region (3.3) also apply to use-declarations.
AND (3.3.7. Class)
4) A name declared inside a member function obscures the declaration of the same name whose scope extends or ends with a member of the function class.
source to share