I have a simple question for namespace in C++. There are errors when I compiling the following little piece of code. I don't understand why. Thanks for any help in advance!
#include <iostream>
using namespace std;
int x=100;
namespace first
{
int x=1;
}
namespace second
{
int x=2;
}
int main(){
{
using namespace first;
cout<<x<<endl;
}
{
using namespace second;
cout<<x<<endl;
}
cout<<x<<endl;
}
If I comment out the x declared in the global scope and the last statement. It works fine. But in my mind, the first x is declared in the std namespace and using namespace first and second in the main will be invalid after the the code block they are declared(so the namespace will be std again). So the above code should work. Where am I wrong?
But in my mind, the first x is declared in the std namespace
Your mind is wrong. The using namespace std makes names from std available in the global namespace, it doesn't mean names declared in the global namespace are in std.
x is declared in the global namespace.
so the namespace will be std again
No, nothing in your file is in namespace std, only the contents of <iostream> are in namespace std.
The error is that when you try to use x there are two different variables in scope, ::x and first::x that you could be referring to, so it is ambiguous. You can disambiguate with a using declaration instead of a using directive:
{
using first::x;
cout<<x<<endl;
}
This says that in that scope x refers to first::x
in this case x variable is ambiguous. The compiler can't find which x you are going to use. You can write like this.
#include <iostream>
using namespace std;
int x=100;
namespace first
{
int x=1;
}
namespace second
{
int x=2;
}
int main(){
{
cout<<first::x<<endl;
}
{
cout<<second::x<<endl;
}
cout<<x<<endl;
}
now your code will compile.
The first x is not in the std namespace. It would only be in the std namespace if defined like this:
namespace std
{
int x;
}
Because it's not in that namespace, it's matched by references to x later in the program, and such references become ambiguous when another namespace declaring x is also being used (as in using namespace first / second).
Related
This question has alreday discussed in the link
unnamed namespace within named namespace but no perfect answers were provided on how to access the variables of unnamed namespace nested under named namespace in case both variables are same
Consider This Code
namespace apple {
namespace {
int a=10;
int b=10;
}
int a=20;
}
int main()
{
cout<<apple::b; //prints 10
cout<<apple::a; // prints 20
}
Unnamed namespace "variable a" is always hidden. How to access "variable a" of unnamed namespace?
Is it even legal to declare unnamed namespaces inside named namespaces?
unnamed namespace "variable a" is always hidden. How to access "variable a" of unnamed namespace?
It looks like you simply cannot qualify an unnamed namespace outside of the enclosing namespace.
Well, here's how to fix the ambiguity:
namespace apple {
namespace {
int a=10;
}
int getPrivateA() {
return a;
}
int a=20;
}
int main() {
cout<<apple::getPrivateA() << endl;
cout<<apple::a << endl;
}
See the Live Demo.
Though I'm aware that doesn't fully answer your question (besides if it's legal to nest unnamed namespaces inside another namespace).
I'll have to investigate what the c++ standard specification with chapters 3.4 and 7.3 a bit more to give you a definite answer why it's not possible what you want to do.
I read this the other day and have an answer for "How to access "variable a" of unnamed namespace?"
I answer this knowing fully that it isn't a perfect answer, but it is a way to access the "a" from the unnamed namespace.
#include <iostream>
#include <stdio.h>
namespace apple {
namespace {
int a=257;
int b=10;
}
int a=20;
}
using namespace std;
int main() {
int* theForgottenA;
// pointer arithmetic would need to be more modified if the variable before
// apple::b was of a different type, but since both are int then it works here to subtract 1
theForgottenA = &apple::b - 1;
cout << *theForgottenA; //output is 257
}
I am trying to write a function which takes two numbers and prints out their sum.
#include <iostream>
using namespace std;
int plus(int, int);
int main () {
int a, b, result;
cout << "2 numbrs";
cin>>a>>b;
result = plus(a,b);
cout << result;
return 0;
}
int plus(int a,int b) {
int sum;
sum = a+b;
return sum;
}
and error I get:
use of `plus' is ambiguous
It´s my first C++ program and in fact I am getting blind finding an error.
Either do
result = ::plus(a,b);
Or rename the function. This is a good lesson on why using namespace std is not considered good practice.
There is already a function object in the std namespace called plus. Because of using namespace std; this std::plus is put in the global namespace, which is also where your plus() is named. When you attempt to call your plus() the compiler can't tell whether you are referring to std::plus or your plus() because they are both in the global namespace.
You have the following options:
Remove using namespace std; (you'll then need to qualify other functions in the std namespace -- e.g. std::cout).
Put your plus() in its own namespace (say, mine), and call it using mine::plus(a, b).
Call your function with ::plus() as suggested (assuming you don't put it in its own namespace).
Rename the function so that there is no name collision.
I am trying to use the directive using namespace NS on a specific member but the compiler doesn't seems to understand so.
This is a very simple sample of code :
namespace NS{
int a;
int b;
}
using namespace NS::a;
int main(){
return 0;
}
Clang compiler returns error: expected namespace name at using namespace NS::a;
a is not namespace. So you can just pull contents of namespace in global namespace with using namespace NS, or pull only a in global namespace with using NS::a.
using namespace NS means that NS is a namespace and you want to have direct access to its scope. So instead of NS::a you can write a directly.
While
using namespace NS::a means that NS is a namespace including another namespace a and you want to have access to variables defined in scope of namespace a !!!
This question already has answers here:
Is using namespace in an anonymous namespace safe?
(2 answers)
Closed 3 months ago.
I want using namespace std; to apply to classes as well as functions without polluting the global namespace, but I'm wondering if it's an ok approach.
namespace
{
using namespace std;
class S
{
public:
S()
{
cout << "ok";
}
friend ostream operator<<(ostream& os, const S& s);
};
}
Any caveats to this?
It will work but keep in mind the following points:
You should limit its use in a source file, not in a header file (in general you should refrain from using unnamed namespaces in headers since they can easily mess around with your symbol definitions, especially if there are inline functions that use something from the anonymous namespace).
It's a bad practice and adding an additional naming hierarchy layer (i.e. the anonymous namespace) just for laziness is as bad as it sounds.
If it's in header file then it's not preferable as this file could be included in multiple source file. If in some source file then its acceptable
Whilst this looked like a great solution, in my experiments it doesn't do as I expected it would. It doesn't limit the scope of the using directive.
Consider this:
#include <string>
namespace {
string s1; // compile error
}
namespace {
string s2; // compile error
}
string s3; // compile error
int main()
{
}
None of those strings compile because they are not properly qualified. This is what we expect.
Then consider this:
#include <string>
namespace {
using namespace std;
string s1; // compiles fine (as expected)
}
namespace {
string t2; // compiles fine (I didn't expect that)
}
string v3; // compiles fine (I didn't expect that either)
int main()
{
}
So placing a using directive within an unnamed namespace appears to be exactly the same as placing it in the global namespace.
EDIT: Actually, placing a symbol in an unnamed namespace makes it local to the translation unit. So this is why it can't work for the intended purpose.
Therefore it has to be a no-no for headers.
An unnamed namespace doesn't contain the effects of a using-directive:
namespace A {int i;}
namespace {
using namespace A;
}
int j=i,k=::i; // OK
Both qualified and unqualified lookup follow the implicit using-directive for the unnamed namespace and then follow the explicit one within it. Wrapping the unnamed namespace inside another namespace limits the unqualified case to other code within that outer namespace, of course:
namespace A {int i;}
namespace B {
namespace {
using namespace A;
}
int j=i; // OK, as above
}
int j=i, // error: i not found
k=B::i; // OK
However, in either case you might as well write the using-directive outside the unnamed namespace (or not write it at all if it would be problematic, perhaps because it would appear in a header file).
Don't take the decision to use an anonymous namespace just so you can limit the scope of a using directive.
That being said, if an anonymous (or any other) namespace is already there and you want the advantages of the using inside it, it's fine as long as your coding standards okay it.
When I use the following
#include <map>
using namespace LCDControl;
Any reference to the std namespace ends up being associated with the LCDControl name space.
For instance:
Generic.h:249: error: 'map' is not a member of 'LCDControl::std'
How do I get around this? I didn't see anything specific to this on any documentation I looked over. Most of them said not to use: using namespace std;.
Here's line 249:
for(std::map<std::string,Widget *>::iterator w = widgets_.begin();
It looks like there's a std namespace within LCDControl that's hiding the global std namespace. Try using ::std::map instead of std::map.
I would say that either there's a using namespace std somewhere within the LCDControl namespace, or possibly there's an #include of a STL header that defines std within the LCDControl namespace.
e.g.:
namespace LCDControl
{
#include <map>
}
Which would define all the symbols in <map> as part of LCDControl::std, which in turn would hide the global std, or at least any symbols defined in the inner namespace, I'm not sure.
When I tried this under VS2008, I got an error:
namespace testns
{
int x = 1;
}
namespace hider
{
namespace testns
{
int x = 2;
}
}
int y = testns::x;
using namespace hider;
int z = testns::x; // <= error C2872: 'testns' : ambiguous symbol
The 'map' class lives in the std namespace, so you are going to have to qualify that somewhere. How are you qualifying your map object? You should have no problem doing this:
std::map<foo> myMap;
You can also do something like this if you do not want to explicitly qualify it every time, but also do not want to pollute your global namespace:
using std::map;