Question

I have a C++ class which declares a single static member. The entire class is contained in a header file and I'd rather avoid creating a .cpp file simply to contain the static member definition. I've been trying to use the static keyword (in the C sense) and anonymous namespaces, both of which should give a variable declared in a header file static linkage (asfaik) but neither approaches work, can anyone give me a solution to this problem?

struct ServiceType {} ;
struct Transport
{
    static ServiceType service ;
};

//error: definition of ‘Transport::service’ is not in namespace enclosing ‘Transport’
//namespace { ServiceType Transport::service ; }

//error: ‘static’ may not be used when defining a static data member
//static ServiceType Transport::service ;
Was it helpful?

Solution

If the goal is just to not have to create a .cpp file, the simplest solution would probably be to wrap the static data member in an inline static member function. In other words, something like:

struct Transport
{
    static ServiceType& service()
    {
        static ServiceType theData;
        return theData;
    }
};

Of course, you'll have to use the syntax service(), rather than just service, to access it.

OTHER TIPS

You cannot define a static member with internal linkage.

If you define the static member service in the header file, you will have an instances in every source, where you include this header file. If this is not a problem, you can wrap an anonymous namespace around the whole struct Transport

namespace {
struct Transport
{
    static ServiceType service ;
};

ServiceType Transport::service;
}

Anonymous namespaces are visible in the whole compilation unit. If you include the header in multiple source files, you will end up with multiple symbols named Transport::service. That doesn't work, as you'll get a symbol already defined error from the linker.

I'm afraid the way C++ works does not allow you to get away with this without moving the definition of the service symbol in a .cpp file.

So, in a .cpp file, either do Transport::ServiceType service; or if you don't want service to be part of a namespace do extern ServiceType service; in the header and ServiceType service; in the .cpp.

Try

ServiceType Transport::service ;

This is wrong:

namespace { ServiceType Transport::service ; } //You are adding it in an unnamed namespace, rather than whatever namespace Transport is actually in - presumably the global namespace

this is wrong:

static ServiceType Transport::service ; // You dont need the static here, only in the struct.

I would expect you will get linker errors if you insist on having it in the header though

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top