Reputation: 948
I am confused about using-directive.
According to C++11 standard §7.3.4 p.3,
A using-directive does not add any members to the declarative region in which it appears.
Additionally, C++11 standard §7.3.4 does not deal with qualified name lookup.
Therefore, IMHO using-directive has no effect to qualified name lookup.
For example, I think that the following sample code should cause a compilation error.
#include <iostream>
namespace A {
namespace B {
int i = 1;
}
using namespace B;
}
int main()
{
std::cout << A::i << std::endl;
}
But both gcc and clang compile this code successfully. (http://melpon.org/wandbox/permlink/rXPjE5k12yMtlvMg)
Furthermore, C++11 standard §7.3.1.1 says that an unnamed-namespace-definition behaves as if it were replaced by
inlineopt namespace unique { /* empty body */ } using namespace unique; namespace unique { namespace-body }
and shows following example (the unnecessary part were omitted).
namespace { int i; } // unique::i
namespace A {
namespace {
int i; // A::unique::i
}
}
using namespace A;
void h() {
i++; // error: unique::i or A::unique::i
A::i++; // A::unique::i
}
This example says that A::i
of function h
can refer to the unnamed namespace member i
.
Help me, I cannot understand any longer.
Would you teach me the right interpretation of using-directive?
Upvotes: 8
Views: 194
Reputation:
Having 7.3.4
A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup (3.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]
A using-directive does not add any members to the declarative region in which it appears.
Interpreting above it says a using-directive is pulling the names into a scope, but not the declaration (namespace member), itself.
This might illustrate it:
namespace N {
template <typename T> void f() {};
}
using namespace N;
// error: specialization of ‘template<class T> void N::f()’ in different
// namespace
template <> void f<int>() {};
In the second example there are two unnamed namespaces:
Applying some little changes:
#include <iostream>
namespace { int i = 0; } // unique::i
namespace A {
namespace {
int i = 1; // A::unique::i
}
}
using namespace A;
int main () {
// i++; // error: unique::i or A::unique::i
// The i having the value 1:
std::cout << A::i << std::endl; // A::unique::i
return 0;
}
Upvotes: 2