I'm generating an constexpr std::array
inside of a constexpr
class, but I only want one instance of that class over all of the project where it is used.
I had originally made it a global, but then I found out that these globals are duplicated if I iterate over the array in multiple translation units. I then attempted to use a constexpr
function, but I can't have a static
inside of such a function. I'm using c 14, so I can't use an inline constexpr
variable. An extern constexpr
variable doesn't make sense because if you separate the declaration from the definition, then how can the constexpr
values be dealt with in a compile time rather than a runtime manner when only one item is needed?
Are there any other options?
EDIT: See https://godbolt.org/z/5PcboYov4
Please remember that I'm not defining a regular variable. I'm defining a constexpr
variable. The difference is IMPORTANT. It is being used in both non-constexpr
and constexpr
contexts.
CodePudding user response:
Variable templates have external linkage, even if they are const
-qualified:
template<typename = void>
constexpr std::array my_array{/*...*/};
// use my_array<> to access the array.
This is however only since DR 2387, which I guess should also apply to C 14 although it was resolved only in 2019.
If the compiler does not implement it, then you can add extern
explicitly. As far as I can tell that is allowed and the declaration will still be a definition because it has an initializer. Because it is a template, there is no ODR violation for multiple definitions:
template<typename = void>
extern constexpr std::array my_array{/*...*/};
// use my_array<> to access the array.
I do not believe that it is possible to give a constexpr
-qualified non-template variable external linkage and ODR-use it in multiple translation units before C 17 which introduced inline
variables for exactly this purpose.