How to have static data members in a header-only l

2019-01-06 19:35发布

问题:

What is the best way to have a static member in a non-templated library class, without placing the burden of defining the member on the class user?

Say I want to provide this class:

class i_want_a_static_member
{
    static expensive_resource static_resource_;

public:
    void foo()
    {
        static_resource_.bar();
    }
};

Then the user of the class must not forget to define the static member somewhere (as already answered many times):

// this must be done somewhere in a translation unit
expensive_resource i_want_a_static_member::static_resource_;

I do have an answer below, but it has some disadvantages. Are there better and/or more elegant solutions?

回答1:

You can use function local static variables.

struct Foo {
     static int& Bar() { static int I; return I; }
}; //                    ^~~~~~~~~~~~


回答2:

My own solution is to use a templated holder class, as static members work fine in templates, and use this holder as a base class.

template <typename T>
struct static_holder
{
    static T static_resource_;
};

template <typename T>
T static_holder<T>::static_resource_;

Now use the holder class:

class expensive_resource { /*...*/ };

class i_want_a_static_member : private static_holder<expensive_resource>
{
public:
    void foo()
    {
        static_resource_.bar();
    }
};

But as the name of the member is specified in the holder class, you can't use the same holder for more than one static member.



回答3:

As of C++ 17. You can now use inline variables to do this:

static const inline float foo = 1.25f;