c++static-initialization

How do I solve this static initialisation order problem?


I have a counter which is a static variable, and I want to be able to register objects anywhere in my source code like this:

struct Registry
{
    static inline int counter;

    static int getCounter() { return counter; }

    static int registerObject()
    {    
        return counter++;
    }    
};

int object_with_unique_id = Registry::registerObject();

The objects are not guaranteed to be in the same translation unit, so a bunch of objects may be registered, incrementing the counter, and then the program may initialize counter to 0, which won't work.

I could put counter in a function as a static, which will be initialized when it's first called, so I can put it in registerObject():

static int registerObject(){ 
     static int counter = 0;
     return counter++;
}

But, now counter isn't in any other scope, and I can't 'get' it. How do I solve this problem?


Solution

  • This can be achieved using a private getter that returns a reference:

    static int& counter() {
        static int counter = 0;
        return counter;
    }
    
    static int registerObject() {
        return counter()++;
    }
    
    static int getCounter() {
        return counter();
    }