How to define a static member of a constexpr array to specialize a template class

I am trying to use constexpr static arrays in a specialized template class, as shown below:

///////////////////////////////////////////////////////////////////////////
struct good {
    static constexpr int values[1] = { 0 };
};

constexpr int good::values[1];

///////////////////////////////////////////////////////////////////////////
template <typename T>
struct bad;

template <>
struct bad<int> {
    static constexpr int values[1] = { 0 };  
};

constexpr int bad<int>::values[1];

///////////////////////////////////////////////////////////////////////////
int
main (int argc, char **argv)
{
#if 1
    return good::values[0];
#else
    return bad<int>::values[0];
#endif
}

I am aware of the requirement to both declare and define static members, and the “good” case above will succeed with gcc-6.2.0 and clang-3.9.0 using -std = C ++ 1z.

However, a “bad” case results in an undefined link in the clang-3.9.0 section, giving the result as follows:

danny@steve ~/src $ clang++ -std=c++1z scratch.cpp
/tmp/scratch-56fa44.o: In function `main':
scratch.cpp:(.text+0x15): undefined reference to `bad<int>::values'
clang-3.9: error: linker command failed with exit code 1 (use -v to see invocation)

Is there anything extra I need to do, or what I am missing to create the static constexpr members? The code seems to work just fine when changing to use static constant elements.

The code will be successfully linked if the block is compiled with -std = C ++ 1y.

+4

Source: https://habr.com/ru/post/1663583/


All Articles