Note that std :: make_shared takes a parameter by reference, which leads to Config::a odr-used , since it will be bound to the reference parameter, then it needs to be defined in the namespace area (before C ++ 17).
On the other hand, std::cout << Config::a will not use Config::a to use odr, because std :: basic_ostream :: operator <<<<<<<<<<<<<<<<<< <; (int) takes a parameter by value, Config::a then undergoes the lvalue-to-r transformation requested to copy-initialize the parameter, so Config::a not used odr.
If an object is used by odr, its definition must exist. You can add a definition (to the implementation file) as
constexpr int Config::a;
Note that it cannot have an initializer.
Live
Since the C ++ 17 constexpr static data element is implicitly embedded, then such a definition is not required again, so your code works well from C ++ 17.
If the static data member is declared constexpr , it is implicitly inline and does not need to be updated in the namespace scope. This update without an initializer (previously required as shown above) is still allowed, but is deprecated.
Live
source share