Can you explain why this code works and prints 16;
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using namespace X;
}
int main()
{
std::cout << Y::p;
}
and why this code throws error of multiple declaration
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using X::p;
}
int main()
{
std::cout << Y::p;
}
I have heard that using directive isn't simply the process of using declaration of any name, as it seems to work differently
But I can't understand why, could you give some detailed explanation ??
similarly this one works fine printing 16, if I replace using the directive with just the declaration of X::p it will throw the same error
#include <iostream>
namespace X {
int p = 5;
}
int p = 16;
using namespace X;
int main()
{
std::cout << ::p;
std::cout << "\n";
return 0;
}
The key difference is that a using declaration is, well, a declaration. While a using directive is not. Sounds stupid, I know, but that's the nature of the difference. The former actually adds declarations to a declarative region, while the latter only makes certain names usable in a declarative region.
Making a name usable in a certain scope, as opposed to declaring it, is intended to be a much weaker thing. The former is not considered during qualified lookup, if there's another declaration with the same name, as [basic.scope.hiding]/4 says:
And that pretty much explains your first code snippet. There's a declaration for that name, on account of the using declaration, so the name made visible by the using directive isn't considered. Doesn't matter which comes first, a declaration is always stronger.
Your second code snippet has two declarations for
p
inY
. And when it comes to those, the usual rules for declarations apply. The second one must declare the same thing, or the program is ill-formed. Nothing more to it, really.Finally, in your third code snippet, it's more of the same as in your first code snippet. [basic.lookup.qual]/4 says this:
So other than the namespace being looked up, everything else is just like your first example. You both declare it, and make it available by the using directive. The first paragraph I quoted determines which one must be picked.