Namespaces
Namespaces create separation of symbols and names in C++. This allows for types, functions and variables to have the same name without causing collisions and ambiguity. We have already been using a namespace throughout this series, this being the std
namespace. Namespaces a named scopes whose members can be accessed using the scope resolution operator ::
. To create a namespace you use the namespace
keyword followed by the namespace name and a new scope. To use a namespace without having to go through scope resolution you can declare a namespaces use by using namespace /* name */
.
Note: Using
::
with no name looks in the global namespace eg.::a
.
#include <iostream>
namespace A
{
auto f(int n)
-> void
{ std::cout << n << '\n'; }
}
auto f(int n)
-> void
{ std::cout << "3 + n:(" << n << ") = " << 3 + n << '\n'; }
auto main() -> int
{
// using namespace A; ///< Error: overload is ambiguous (redefinition)
f(8);
A::f(8);
return 0;
}
Duplicate Namespaces
Two namespaces with the same name will logically be merged, members and symbols from both can be looked up using the same namespace name given both headers containing the namespace symbols is available to be searched. This is how the std
namespace can have all its components across different headers but be looked up using std::
.
#include <iostream>
namespace A
{
auto f(int n)
-> void
{ std::cout << n << '\n'; }
}
namespace A
{
auto g(int n)
-> void
{ std::cout << "3 + n:(" << n << ") = " << 3 + n << '\n'; }
}
auto main() -> int
{
A::f(8);
A::g(8);
return 0;
}
Nested Namespaces
Namespaces can also be declared to be nested. We saw this in the previous set of sections with the std::placeholders
namespace. To access a nested namespace you use a double scope resolution operator ::
.
#include <iostream>
namespace A
{
auto f(int n)
-> void
{ std::cout << n << '\n'; }
namespace B
{
auto f(int n)
-> void
{ std::cout << "3 + n:(" << n << ") = " << 3 + n << '\n'; }
}
}
auto main() -> int
{
A::f(8);
A::B::f(8);
return 0;
}