Home > Software engineering >  How to define a constexpr constructed array that will have only one instance over many translation u
How to define a constexpr constructed array that will have only one instance over many translation u

Time:01-05

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.

  • Related