C++ Namespace scope bug / feature
-
Just ran into something I thought was odd today, if you had the following
namespace A
{
enum Things
{
Apple,
Orange,
HamSandwich,
RocketPoweredElephant
};void Function(Things thing) { }
}
namespace B
{
void Function(A::Things thing)
{} void Ambiguous() { Function(A::Orange); //Error - Ambiguous call }
}
void main()
{
Function(A::Orange); //Will call A::Function
}Because one of the parameters is type contained within namespace A,
A::Function
is being brought into scope, causing an error for the functionAmbiguous
. Is this part of the spec or is it some compiler (VS2012) jiggery pokery? -
Just ran into something I thought was odd today, if you had the following
namespace A
{
enum Things
{
Apple,
Orange,
HamSandwich,
RocketPoweredElephant
};void Function(Things thing) { }
}
namespace B
{
void Function(A::Things thing)
{} void Ambiguous() { Function(A::Orange); //Error - Ambiguous call }
}
void main()
{
Function(A::Orange); //Will call A::Function
}Because one of the parameters is type contained within namespace A,
A::Function
is being brought into scope, causing an error for the functionAmbiguous
. Is this part of the spec or is it some compiler (VS2012) jiggery pokery?I assume it's part of the spec, based on the following error messages:
AConsole.cpp
1>c:\users\richard\documents\visual studio 2010\projects.c++\aconsole\aconsole\aconsole.cpp(98): error C2668: 'B::Function' : ambiguous call to overloaded function
1> c:\users\richard\documents\visual studio 2010\projects.c++\aconsole\aconsole\aconsole.cpp(91): could be 'void B::Function(A::Things)'
1> c:\users\richard\documents\visual studio 2010\projects.c++\aconsole\aconsole\aconsole.cpp(83): or 'void A::Function(A::Things)' [found using argument-dependent lookup]
1> while trying to match the argument list '(A::Things)' -
Just ran into something I thought was odd today, if you had the following
namespace A
{
enum Things
{
Apple,
Orange,
HamSandwich,
RocketPoweredElephant
};void Function(Things thing) { }
}
namespace B
{
void Function(A::Things thing)
{} void Ambiguous() { Function(A::Orange); //Error - Ambiguous call }
}
void main()
{
Function(A::Orange); //Will call A::Function
}Because one of the parameters is type contained within namespace A,
A::Function
is being brought into scope, causing an error for the functionAmbiguous
. Is this part of the spec or is it some compiler (VS2012) jiggery pokery?It's Argument Dependent Lookup (ADL) also known as Koenig lookup. It's invaluable when you're trying to define operations on a type in a namespace using functions in that namespace. Say you have:
namespace N
{
class A
{};friend A operator+( const A &, const A& );
}
// Somewhere else...
A a, b;
auto c = a + b;
if the compiler didn't know to look for the operator in the namespace A was declared in you wouldn't be able to use operator functions in namespaces that easily. It would be a particular headache for <, << and >> which are required by chunks of the standard library.
-
It's Argument Dependent Lookup (ADL) also known as Koenig lookup. It's invaluable when you're trying to define operations on a type in a namespace using functions in that namespace. Say you have:
namespace N
{
class A
{};friend A operator+( const A &, const A& );
}
// Somewhere else...
A a, b;
auto c = a + b;
if the compiler didn't know to look for the operator in the namespace A was declared in you wouldn't be able to use operator functions in namespaces that easily. It would be a particular headache for <, << and >> which are required by chunks of the standard library.
Super. I've probably got operator functions around that work because of this, I've just never noticed or thought about it before.