I have a header-only project. Inside it I have a class. Inside it (or anywhere else actually) I would like to have constant data (enum values to string and vice-verse). This problem seems a lot harder that I expected.
typedef boost::bimap<MyEnum,std::string> Data;
What I tried and did not work:
static Data const s_data = _initData();
: Error is like: only static const integral data members can be initialized within a class
.
static Data const * const s_pData = _initData();
: The _initData()
function had a static local variable (which became filled on first call), and returned the address of it. Did not work with the same reason as above.
What I tried and worked, but I consider it ugly:
class Ugly {
public:
static MyEnum lookupByName(std::string s)
{
MyEnum ret;
lookup(ret,s,true);
return ret;
}
static String lookupByEnum(MyEnum e)
{
std::string ret;
lookup(e,ret,false);
return ret;
}
static void lookup(MyEnum &e, std::string &s, bool etos)
{
static Data s_data = _fill();
if(etos)
s = /* ... */;
else
e = /* ... */;
}
static Data _fill(){ /* ... */ };
};
Ideas?
The simpler is
static T& global_t()
{ static T z = initializer; return z; }
global_t()
can be used whereve a T value is required.
NOTE:
In answer to rioki comment, we must also specify the function as inline
if it is at global or namespace level (to avoid the "multiple instances" problem towards the linker).
The inline keyword is not necessary if the function is a template or is a class member-function (for which the inline definition is by default)
If the static T
instantiation must be shared among different OS modules (read: DLLs) rioki is perfectly right, but -at that point- a header-only library makes no more sense.
Starting from C++17, the inline
specifier can also be used on variables.
So, from C++17 onward, you can just write
inline T global_object = initializer;
You can also use inline for static members of function, to provide inline initialization, like
class Class
{
static inline Type static_object_name = initializer;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With