The following source code compiles correctly with Visual Studio 2010:
namespace NS
{
class X
{
};
X Y(X str);
}
void myFun()
{
NS::X x;
Y(x);
}
(this is reduced code where all my own class and function names have been replaced by X, Y, ...)
I would expect that the line Y(x)
would fail to compile, since it should be NS::Y(x)
.
This source code is compiled with the following command
cl /c file.cpp
There are no other files included here, no other command line options.
Why does this file compile?
Bug in VS2010? Or something that I (and my 3 other colleagues) overlooked?
What you are experiencing is due to ADL
(Argument Dependent Lookup).
There is nothing wrong with your snippet (besides the fact that the linker will probably complain about NS::Y
isn't defined), but it should compile - VS2012 is handling the snippet as it should.
The compiler will find NS::Y
due to the fact that the type of parameter x
(NS::X
) is in the appropriate scope.
3.4.2 Argument-dependent name lookup [basic.lookup.argdep]
When an unqualified name is used as the postfix-expression in a
function call (5.2.2), other namespaces not considered during the
usual unqualified lookup (3.4.1) may be searched, and in those
namespaces, namespace-scope friend function declarations (11.4) not
otherwise visible may be found.
These modifications to the search depend on the types of the
arguments (and for template template arguments, the namespace of the
template argument).
For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more
associated classes to be considered.
The sets of namespaces and
classes is determined entirely by the types of the function arguments
(and the namespace of any template template argument).
It is valid C++ code. It is compiled since argument-dependent lookup applies here.