1) `semi::static_map` gives you the optional run-time look-up with the same API (`semi::static_map::get`). Looking up a global variable with a runtime key isn't straight-forward. This makes it particularly nice to use an API where a function might take either a compile-time or run-time key. I'm thinking a Font API with a `getFont` method, for example. The way you use the method is the same regardless if you are using a compile-time key or not.
2) `semi::static_map` also gives you control over the lifetime of the objects. For example, it's easy to delete all the values in the map at once. Again, this is not straight-forward to do with a bunch of globals.
3) the keys are also values themselves and it's straight-forward to evaluate them at run-time. Printing the name of a global variable, for example, requires all sorts of hackery.
4) you do not need to know all your keys in advance. Simply using getFont with a unique constexpr key will create a new global variable.
Edit: added point (4)
enum {
KEY_FOO,
KEY_BAR,
KEY_BLAH,
NUM_KEYS,
};
struct KeyInfo {
const char *name;
int info1;
float info2;
};
const static struct KeyInfo keyInfo[NUM_KEYS] = {
#define MAKE(x, y, z) [x] = { #x, y, z }
MAKE( KEY_FOO, 1, 1.0 ),
MAKE( KEY_BAR, 7, 3.5 ),
MAKE( KEY_BLAH, 42, 127.2 ),
#undef MAKE
};
void print_key(int key)
{
printf("%d's name is %s\n", key, keyInfo[key].name);
}
It's both low-tech and maintainable. It compiles super quick. If one doesn't like that one has to type KEY_FOO twice (in the enum and in the array definition), one can use X-macros or code generation. But personally I don't care.The `semi::static_map` does not require this.This is especially useful if you are writing library code: imagine you are programming a `getFont` method - you don't know with which constexpr keys your method will be called, so there is no way for you to list all these keys in an enum.
class foo {
public:
foo();
~foo();
};
foo::foo() { }
foo::~foo() { }
Ad nauseum.Oh, but C++ can eliminate redundancy in this one cool case I'm thinking of!
As stated in the talk, the main use case for a map like this is to cache objects which are expensive to load/compute (again something like `getFont` comes to mind). In these use-cases you would likely also need a check like this anyway: a global pointer object which you need to check if it's a nullptr or not before using it.
The last paragraph was just arcana though. You should be passing -fvisibility=hidden and explicitly exporting from your DSO only the symbols you might legitimately expect some other DSO to use, obviating the issue.