I am currently confused with the way "using (namespace)" statements work in C++.
I have:
//somewhere in included headers
typedef unsigned int uint;
namespace mine {
typedef unsigned int uint;
}
namespace other {
using namespace mine;
void foobar () {
uint offender = i;
}
}
Results in (paraphrased):
reference to 'uint' is ambiguous. candidates are typedef unsigned int uint and typedef unsigned int mine::uintMeanwhile, when I do
namespace other {
using namespace 开发者_开发百科mine;
using mine::uint;
void foobar () {
uint offender = i;
}
}
Everything works fine. It seems strange to me that "using identifier;" changes the visibility of other typedef definition (conceals the global one?). Can someone point me to what kind of rules in C++ govern resolution of typedefs across namespaces?
A name made visible by a using-directive appears in the nearest enclosing scope that contains [- directly or indirectly -] both the using-directive and the nominated namespace. (7.3.4 [namespace.udir])
This means that both uint
declarations appear at the global namespace scope when looked up after the using-directive in other
.
A using-declaration, like any other declaration, declares a name at the scope in which it appears. This is why, in the second example, using mine::uint;
hides the uint
introduced by using namespace mine;
as the latter appears to come from the global scope.
Your original code confuses the compiler, because the uint can be either
::uint
or
::mine::uint
therefore compiler throws that error message to you. In the "fix", the using mine::uint
explicitly specified that ::mine::uint
shall be preferred.
However, typedef
conflict shall be avoided IMO. It makes the code so hard to maintain.
I can't cite chapter and verse for you, but this makes sense to me. If the compiler can't find the symbol uint
in the current namespace, it looks to other namespaces to see if it can find the symbol there. Since it finds it in two other namespaces, it's ambiguous.
When you said using mine::uint
you imported that symbol into the current block, so it's found before the other namespaces need to be checked.
It doesn't conceal the global one. That's why you have the ambiguity.
精彩评论