§3.4.6/1:
In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier only namespace names are considered.
Basically, what I'm asking is: "why is this paragraph necessary?"
§3.4.6/1:
In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier only namespace names are considered.
Basically, what I'm asking is: "why is this paragraph necessary?"
Defect report 373: Lookup on namespace qualified name in using-directive gives an example of why the wording matters:
namespace X {
namespace Y {
struct X {
void f()
{
using namespace X::Y;
namespace Z = X::Y;
}
};
}
}
Which X
is being referred to in using namespace X::Y
the struct or the namespace? Without that wording in 3.4.6
it would be ambiguous.
This actually lead to the change in the wording from:
When looking up a namespace-name in a using-directive or namespace-alias-definition, only namespace names are considered.
to what we have today because the original wording did not cover the nested-name-specifier.
The ambiguity is with the nested-name-specifier which if we look at the draft C++11 standard the grammar in section 5.1.1
General is as follows:
nested-name-specifier:
::opt type-name ::
::opt namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier templateopt simple-template-id ::
and the following paragraphs which I won't copy since they are large do not restrict nested-name-specifier to a namespace.
As far as I can tell section 7.3.1
Namespace definition sufficiently restricts namespace-name to prevent ambiguities.
Clang's unit tests for namespace using
and alias directives
is exactly the answer to your question:
clang-cc -fsyntax-only -verify %s
struct ns1 {}; // This is not a namespace, although a namespace has ns1 as a name
void ns2();
int ns3 = 0;
namespace ns0 {
namespace ns1 {
struct test0 {};
}
namespace ns2 {
struct test1 {};
}
namespace ns3 {
struct test2 {};
}
}
using namespace ns0;
namespace test3 = ns1; // don't get confused
namespace test4 = ns2;
namespace test5 = ns3;
using namespace ns1; // don't get confused
using namespace ns2;
using namespace ns3;
test0 a;
test1 b;
test2 c;
This issue has also been discussed in n3160 defect report