I am trying to access variable x using using directive in the following code:
#include <iostream>
using namespace std;
int x = 10;
namespace e {
int x = 5;
}
int main() {
using namespace e; // Because of this line compiler shows error
cout << x;
return 0;
}
In general we use the following line to access x but I am getting error We can also use using e::x; But my question is why can't we use using namespace e;
In this example it may seem that using namespace e;
makes names from namespace e
available in main
function scope. However it does not do this. Instead it tries to inject names (during unqulified lookup in main
) from namespace e
into the nearest enclosing namespace of main
and namespace e
, to the global namespace that is. Therefore x
becomes ambiguous.
Let's start with another example.
const int x = 10;
namespace e {
const int y = 5;
}
int main()
{
std::cout << e::y;
using namespace e;
std::cout << y;
}
There is variable with value 10 and name x
in global namespace (which can be referred to as x
simply) and variable with value 5 with name y
in namespace e
(which must be referred to as e::y
).
By adding using namespace e;
, you inject all names from namespace e
into global namespace. This means global namespace now contains names x
and y
, and namespace e
contains name y
. You can now refer to variable with value 5
using both y
and e::y
.
Now, back to your example. If we change y
to x
:
const int x = 10;
namespace e {
const int x = 5;
}
int main()
{
std::cout << e::x;
using namespace e;
std::cout << x;
}
There is x
in global namespace and x
in namespace e
. By adding using namespace e;
you inject all the names from namespace e
to global namespace, so now global namespace contains names x
and x
, and namespace e
contains name x
. See the problem? Global namespace contains two names x
, which confuses the compiler. When you try to print variable under the name x
, compiler looks up names in global namespace and finds two x
. It cannot choose which one you meant, so it throws error.
This is the main reason why using namespace
(particularly using namespace std;
) is considered evil . One can easily break working code by updating a library or introducing a new function. Compiler error is best outcome in such a case, but sometimes it's possible that compiler will silently replace one function by another, because it matches better.
You can still access both variables using fully qualified names :
int main()
{
using namespace e;
std::cout << ::x << " "; //x from global with fully quafilied name
std::cout << ::e::x << " "; //x from namespace e with fully qualified name
std::cout << e::x; //not fully qualified, but not ambiguous either - only one x in namespace e
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.