I want a header file with a non-integral constant in it, e.g. a class. Note the constant does not need to be a compile-time constant.
static const std::string Ten = "10";
This compiles but is undesirable as each compilation unit now has its own copy of Ten.
const std::string Ten = "10";
This will compile but will fail with a linker error for multiply defined Ten.
constexpr std::string Ten = "10"s;
This would work but only if the strings constructor was constexpr as well. It will be but I can’t count on every non-integral constant to have a constexpr constructor … or can I?
extern const std::string Ten = "10";
This seems to work but I’m afraid I’ll get a linker error if I breath on it wrong.
inline const std::string Ten( ) { return "10"; }
This has everything I want except a clean syntax. Plus now I have to refer the constant as a function call, Ten().
inline const std::string = "10";
This seems to be the ideal solution. Of course inline variables aren’t allowed by the standard.
- Is there something in the c++ standard that says the extern version should work or am I just lucky it works with GCC?
- Is there a compelling reason not to allow inline variables?
- Is there a better way with c++03 or will there be a better way in c++0x?
You seem to have them mixed up.
You are right about
version. It will “work”, but it will create a separate object in each translation unit.
The version without
staticwill have the same effect. It won’t produce linker errors, but will define a separate object in each translation unit. In C++ languageconstobjects have internal linkage by default, meaning thatis exactly equivalent to the previous version with
static.The version with
externand initializerwill produce a definition of an object with external linkage (it is a definition because of the presence of an initializer). This version will result in linker errors, since you’ll end up with multiple definitions of an object with external linkage – a violation of ODR.
Here’s how you can do it:
In order to achieve what you are trying to achieve, you have to declare your constant in the header file
and then define it (with initializer) in one and only one of the implementation files
(If the constant is pre-declared as
extern, thenexternin the definition is optional. Even without an explicitexternit will define a const object with external linkage.)