Namespace (C++)
https://www.geeksforgeeks.org/namespace-in-c/
A namespace defines a scope in which we can declare or define variables, methods, and classes.
using namespace std;
- this is actually really bad in practice
Why do we even need namespaces?
To prevent name collisions.
Consider the
std
library, which has astring
. Now, you might usestd::string
, or you might want to use your own string implementation, ex:robotics::string
. Without namespaces, one would bestring
, the other could beRoboticsString
, but the alternative is to provide namespaces to avoid this.
Resources
Ooh, there even is a connection to Multiple Inheritance, where you saw you can access member variables using d.B::a
.
No need to indent namespaces
Usually, for readability, we indent our code after using a tab. But no need for namespaces.
Basic Namespace Usage
#include <iostream>
namespace example
{
void dummy() { std::cout << "Dummy\n"; }
}
namespace buzz
{
void test() { example::dummy(); }
}
int main()
{
buzz::test();
}
- Source: https://stackoverflow.com/questions/5619595/how-do-i-call-a-function-in-a-different-namespace
namespace n1 {
namespace n2 {
// code declarations
void f1():
}
}
using namespace n1::n2;
void f2() {
f1();
}
But using namespace
is bad because the whole point of having namespaces is so that it is clear where this function call is coming from.
namespace n1 {
void f2() {
n2::f1();
}
}
Nested Namespace
During my time at NVIDIA, I saw layers of namespaces being used. It wasn’t clear to me how namespaces actually work.
https://medium.com/swlh/all-about-namespaces-fa9a597ed0d4
I am confused on access
What if you are inside namespace
n2
, and want to call functions defined from inside namespacen1
?Ahhh, it’s important that you understand scopes and scope resolution.
Scope of namespaces
In C++, the scope of a namespace extends throughout the entire program. When you declare multiple namespaces with the same name, their members are effectively merged. This is called namespace extension.
In simple terms, this means that you can access all parent namespaces.
Consider the following example:
#include <iostream>
namespace A {
namespace B {
void hello() { std::cout << "hello world";}
namespace C {
void test() {
hello(); // allowed
/* Any of these would also work:
B::hello();
A::B::hello();
::A::B::hello();
*/
}
}
}
}
- When
test()
tries to callhello()
, it first tries to call it from its current
::A::B::C::hello()
→does not workA::B::hello()
→ works!
Any of the following instead of hello()
would also work.
Consider this following example:
#include <iostream>
namespace A {
namespace D {
void hello() { std::cout << "hello world";}
}
}
namespace A {
namespace B {
namespace C {
void test() {
D::hello(); // allowed
A::D::hello(); // allowed
::A::D::hello(); // allowed
hello(); // NOT allowed
}
}
}
}
- Here,you actually don’t have access to namespace
D
, so if you try callinghello()
on its own from within namespaceC
, it will fail. However, namespaceD
is accessible from within namespaceA
, and sinceC
is nested inside namespaceA
, you simply need to specify namespaceD
to be able to call thehello()
function.
Global Namespace (prepending ::
)
This is a small distinction to understand the point of having ::
in front, which I saw myself in NVIDIA codebase.
#include <string>
// Both of these are correct, but what is the difference?
std::string s;
::std::string s;
The difference is that without the ::
in front ( std::string
), the resolution is done from the current scope, while having the ::
in front makes it search from the root namespace (and thus clearer, the tradeoff is that it is overkill mosttimes) (::std:string
)
Here is another example from StackOverflow
namespace A
{
namespace B
{
class C;
}
}
namespace B
{
class C;
}
namespace A
{
using B::C; // resolves to A::B::C
using ::B::C; // resolves to B::C
// (note that one of those using declarations has to be
// commented for making this valid code!)
}
If you want to access starting from global namespace, you start with ::
, something like
namespace n1 {
namespace n2 {
::z1::z2::functionCall();
}
}
Anonymous Namespaces
What happens when you use namespace
without specifying an actual name? Who can actually use it?
It is only accessible from within the same file. Doesn’t have to be inside the brackets.
- though it seems that if you include the file, you can use it?
Anonymous Namespaces
Anonymous namespaces are use is to make functions/objects/etc accessible only within that file. It’s almost the same as static in C.
namespace robotics {
namespace calibration {
namespace {
void doSomething();
}
}
}
In some sense, that isn’t different from declaring a static function, is it?