Reputation: 7506
I know what ADL is and I know in C++, inner scope function hides outer scope functions. That is, names do not overload across scopes. So funtion overloading need to be done in the same scope.
So now my question is, for this common code snippet:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
namespace Foo{
class Bar{
friend void swap(Bar& a, Bar& b);
};
void swap(Bar& a, Bar& b){
cout << "I am here" << endl;
}
}
int main(int argc, char *args[]){
Foo::Bar a, b;
using std::swap; //These 2 lines
swap(a, b); //output is "I am here", Foo::swap is called
}
Along with ADL, is:
custom swap
and std::swap
are both visiable and considered as overloaded, and then choose the best match?
custom swap
is found first then name lookup stops (std::swap
is hidden)?
If 1.
is true, how does it work? Function overloading over 2 different scopes? This contradicts what I write at the beginning. using std::swap
introduce std::swap
to current scope. And custom swap
is in Foo::swap
.
Btw, this answer What is “Argument-Dependent Lookup” (aka ADL, or “Koenig Lookup”)? seems to indicate that they are function overloading.
Further, if for some reason both
A::swap(A::MyClass&, A::MyClass&)
andstd::swap(A::MyClass&, A::MyClass&)
are defined, then the first example will callstd::swap(A::MyClass&, A::MyClass&)
but the second will not compile becauseswap(obj1, obj2)
would be ambiguous.
If it's function overloading, why does my swap(Bar& a, Bar& b)
not has the ambiguity issue as he describes? Is he wrong?
if 2.
is true, according to C++ Primer 5th 18.2.3:
std::cin >> s;
is equivalent to:
operator>>(std::cin, s);
In this example, when the compiler sees the “call” to
operator>>
, it looks for a matching function in the current scope, including the scopes enclosing the output statement. In addition, because the>>
expression has parameters of class type, the compiler also looks in the namespace(s) in which the types ofcin
ands
are defined. Thus, for this call, the compiler looks in thestd
namespace, which defines theistream
andstring
types. When it searchesstd
, the compiler finds thestring
output operator function.
So the name lookup order is: current scope --> enclosing scopes --> argument namespace scope.
Then why is not std::swap
hiding custom swap
? using std::swap
introduces std::swap
to the current scope, which has the higher lookup priority.
Both of my assumptions seems to be invalid in some pionts and I am getting confused. Need some help. Thanks in advance.
Upvotes: 3
Views: 188
Reputation: 172924
1.
is true. For ADL,
These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.
std::swap
is found by usual unqualified name lookup, and Foo::swap
is found by ADL, they're both in the overload set. Foo::swap
is a non-template function which is perferred to std::swap
which is a template in overload resolution.
F1 is determined to be a better function than F2 if implicit conversions for all arguments of F1 are not worse than the implicit conversions for all arguments of F2, and
...
4) or, if not that, F1 is a non-template function while F2 is a template specialization
And about the quote from the linked answer,
if for some reason both
A::swap(A::MyClass&, A::MyClass&)
andstd::swap(A::MyClass&, A::MyClass&)
are defined,
There's no std::swap(A::MyClass&, A::MyClass&)
in fact, it's just an assumption, if there's a non-template std::swap(A::MyClass&, A::MyClass&)
then the invocation would be ambiguous ...
Upvotes: 2