Like it!

Join us on Facebook!

Like it!

C++ namespaces with private members

A cool alternative to the C way of having static global variables.

In C++ you can build beautiful namespaces with private members (variables and functions). This is a good choice when you want to hide the inner workings of a set of utility functions from the final user. You can accomplish that thanks to the concept of anonymous namespaces. An anonymous namespace is a namespace without name, like the following one:

namespace
{
    // your stuff here
}

The beauty of anonymous namespaces is that they are available only in their translation unit, that is the .cpp file they are located.

For example, say I'm working on a small namespace called thing. This is the header file:

// thing.hpp

namespace thing
{
    int getX();
    int getSum();
}

And this is the implementation file:

// thing.cpp

namespace thing
{
    namespace   // anonymous namespace
    {
        int x = 1;
        int y = 2;

        int sum(int a, int b)
        {
            return a + b;
        }
    }

    int getX() 
    {
        return x;
    }

    int getSum()
    {
        return sum(x, y);
    }
};

Notice how I've wrapped the private members in the anonymous namespace. Now only thing can access x, y and sum(). If you try to touch those variables from the outside, an error occurs. Let's try:

#include <cstdio>
#include "thing.hpp"

int main(int argc, char **argv)
{
    printf("%d\n", thing::getX());     // OK
    printf("%d\n", thing::getSum());   // OK
    printf("%d\n", thing::sum(1, 2));  // error: ‘sum‘ is not a member of ‘thing’    
    printf("%d\n", thing::y);          // error: ‘y‘ is not a member of ‘thing’    
}

Sources

Stackoverflow - Why are unnamed namespaces used and what are their benefits? (link)
Wikipedia - Translation unit (link)

comments
Roy on June 17, 2018 at 14:05
Exactly what I needed. Thanks!
Adrian on April 08, 2019 at 15:10
I hope you read this: there's an error on the wikipedia article link (you need to close your parenthesis).
Triangles on April 08, 2019 at 18:35
@Adrian thanks for the feedback, link fixed!
Dan on April 19, 2019 at 22:02
This doesn't seem to work. After testing, I can still access the members in the main file.
maisonsmd on April 28, 2019 at 07:48
Me also, I'm still able to access those member.
D on May 18, 2019 at 20:33
I copy-pasted into repl.it (C++11), and I could still access everything. The StackOverflow link had the same effect.
Triangles on June 03, 2019 at 12:18
@D and others: my wild guess is that this trick works only when you have actual .o files generated by your compiler.
Xiao sings on June 12, 2019 at 06:30
Thanks a lot, dude :)
S on July 07, 2019 at 21:20
I've just tested this with the Microsoft Visual Studio compiler and it didn't let me access anything inside the anonymous namespace.
Dave Smith on July 27, 2019 at 19:48
Thanks, @Triangles, this is very useful! This works for me on Ubuntu 16.04 using g++ 5.4.0. Only minor correction I noticed: your second #include in main should be of "thing.hpp".
Triangles on August 02, 2019 at 12:45
@Dave Smith good catch! Typo fixed. Thank you :)