Namespaces - Examples
This code is fine:
#include <iostream>
using namespace std;
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
int foo = 21; // global, (Also Known As ::foo)
int bar = 22; // global, (Also Known As ::bar)
void f1(void)
{
cout << foo << endl; // unqualified, global (::foo), 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
int main(void)
{
cout << foo << endl; // unqualified, global, 21
cout << ::foo << endl; // qualified, global, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
return 0;
}
Notice the using directive and its placement:
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
using namespace Stuff; // foo is now an alias for Stuff::foo
int foo = 21; // global, ::foo
int bar = 22; // global, ::bar
void f1(void)
{
cout << foo << endl; // unqualified, ambiguous: global (::foo) or alias (Stuff::foo)?
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
int main(void)
{
cout << foo << endl; // unqualified, ambiguous: global (::foo) or alias (Stuff::foo)?
cout << ::foo << endl; // qualified, global, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
return 0;
}
The same using directive is moved and produces different results:
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
int foo = 21; // global, ::foo
int bar = 22; // global, ::bar
void f1(void)
{
cout << foo << endl; // unqualified, global (::foo), 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
using namespace Stuff; // foo is now an alias for Stuff::foo
// bar is now an alias for Stuff::bar
int main(void)
{
cout << foo << endl; // unqualified, ambiguous: global (::foo) or alias (Stuff::foo)?
cout << ::foo << endl; // qualified, global, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
return 0;
}
The same using directive is placed within a function (scope is only in the function):
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
int foo = 21; // global, ::foo
int bar = 22; // global, ::bar
void f1(void)
{
using namespace Stuff; // foo is now an alias for Stuff::foo
// bar is now an alias for Stuff::bar
cout << foo << endl; // unqualified, ambiguous: global (::foo) or alias (Stuff::foo)?
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
int main(void)
{
cout << foo << endl; // unqualified, global (::foo), 21
cout << ::foo << endl; // qualified, global, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
return 0;
}
The same using directive is placed in main after some code:
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
int foo = 21; // global, ::foo
int bar = 22; // global, ::bar
void f1(void)
{
cout << foo << endl; // unqualified, global (::foo), 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
int main(void)
{
cout << foo << endl; // unqualified, global (::foo), 21
cout << ::foo << endl; // qualified, global, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
using namespace Stuff; // foo is now an alias for Stuff::foo
// bar is now an alias for Stuff::bar
cout << foo << endl; // unqualified, ambiguous: global (::foo) or alias (Stuff::foo)?
int foo = 41; // local, hides alias from Stuff::foo
cout << foo << endl; // unqualified, local, 41
cout << ::foo << endl; // qualified, global (::foo), 21
return 0;
}
Now, we are employing the using declaration, and we get very different behavior:
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
using Stuff::foo; // declare foo (from Stuff) here in global namespace
// (it's now the global ::foo)!
int foo = 21; // error, redefinition, foo already declared (must remove this to compile)
int bar = 22; // global, (Also Known As ::bar)
void f1(void)
{
cout << foo << endl; // unqualified, global (::foo aka Stuff::foo), 11
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
void f2(void)
{
int foo = 31; // local, hides global (OK, declaration at different scope)
cout << foo << endl; // unqualified, local, 31
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
int main(void)
{
cout << foo << endl; // unqualified, global (::foo aka Stuff::foo), 11
cout << ::foo << endl; // qualified, global (::foo aka Stuff::foo), 11
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
int foo = 41; // local, hides alias Stuff::foo (OK, declaration at different scope)
cout << foo << endl; // unqualified, local, 41
cout << ::foo << endl; // qualified, global (::foo aka Stuff::foo), 11
return 0;
}
Move using declaration into a new scope (in main):
namespace Stuff
{
int foo = 11; // Stuff::foo
int bar = 12; // Stuff::bar
}
int foo = 21; // global, (Also Known As ::foo)
int bar = 22; // global, (Also Known As ::bar)
void f1(void)
{
cout << foo << endl; // unqualified, global ::foo, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
void f2(void)
{
int foo = 31; // local, hides global (OK, declaration at different scope)
cout << foo << endl; // unqualified, local, 31
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
}
int main(void)
{
cout << foo << endl; // unqualified, global (aka ::foo), 21
cout << ::foo << endl; // qualified, global ::foo, 21
cout << Stuff::foo << endl; // qualified, Stuff::foo, 11
using Stuff::foo; // declare foo (from Stuff) here locally to main
int foo = 41; //error, redefinition, foo already declared in this scope (remove to compile)
cout << foo << endl; // unqualified, local (aka Stuff::foo), 11
cout << ::foo << endl; // qualified, global (::foo), 21
return 0;
}