如何定义模板类专业化的静态 constexpr 数组成员

dcr*_*cro 5 c++ templates clang static-members constexpr

我尝试在模板专用类中使用静态 constexpr 数组,如下所示:

///////////////////////////////////////////////////////////////////////////
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
}
Run Code Online (Sandbox Code Playgroud)

我知道声明和定义静态成员的要求,并且上面的“好”情况似乎使用 -std=c++1z 在 gcc-6.2.0 和 clang-3.9.0 上取得了成功。

然而,“坏”情况会导致 clang-3.9.0 下出现未定义的引用,输出如下:

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)
Run Code Online (Sandbox Code Playgroud)

为了实例化静态 constexpr 成员,是否需要做一些额外的事情,或者我缺少什么?当修改为使用静态常量成员时,代码似乎工作正常。

如果使用 -std=c++1y 编译该单元,则代码将成功链接。

Fed*_*dor 0

是否需要做一些额外的事情,或者我缺少什么来实例化静态constexpr成员?

该代码看起来格式良好,但它确实无法在 Clang 5.0.2 版本中链接,但它在 Clang 6.0 中被完全接受。演示: https: //gcc.godbolt.org/z/Ka7W4bbqf

这表明这只是一个编译器错误。