Consider the code:
template<typename T>
class Foo{};
namespace X
{
class X{};
}
using namespace X; // now both class X and namespace X are visible
Foo<X::X> f()
{
return {};
}
int main() {}
gcc5.2 compiles the code with no errors whatsoever. However clang spits the error:
error: 'X' is not a class, namespace, or enumeration Foo f()
error: reference to 'X' is ambiguous
Is the code syntactically valid, according to the C++ standard? Or is just a gcc bug? Removing the qualified name X::X
and using Foo<X>
instead makes gcc choke also
error: template argument 1 is invalid Foo f()
[namespace.udir]/6:
If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed.
For the first X
in X::X
, both the namespace and the class are considered. However, the name of the namespace resides in the global namespace while the class resides in namespace X
; Hence the above quote applies, Clang is therefore correct. (This also occurs when just writing X
, clearly).
::X
removes this ambiguity. Lookup does not proceed into the namespace anymore. [namespace.qual]/2:
For a namespace
X
and namem
, the namespace-qualified lookup set S(X, m) is defined as follows: Let S0(X, m) be the set of all declarations ofm
inX
and the inline namespace set ofX
(7.3.1). If S0(X, m) is not empty, S(X, m) is S0(X, m); otherwise, […]
Here, X
is the global namespace and m
is "X". Clearly, the declaration of our namespace is found, so lookup is definite here.
Not a complete answer but that is a clear situation that shows even declaring using namespace, for objects with the same name as the namespace you need to declare the namespace.
#include <iostream>
#include <string>
namespace test
{
void function1(void){std::cout << "Function inside the namespace" << std::endl;}
class test
{
public:
static void function1(void){std::cout << "Function inside the class" << std::endl;}
};
};
using namespace test;
int main()
{
function1();
test::function1();
test::test::function1();
}
Output (GCC 4.9.2)
"Function inside the namespace"
"Function inside the namespace"
"Function inside the class"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With