以下C ++ 11程序在gcc和clang中产生对S<42>::s
错误的未定义引用...
#include <iostream>
template<int i> struct S;
template<> struct S<42> { static constexpr char s[] = "foo"; };
int main()
{
std::cout << S<42>::s << std::endl;
}
将以下额外声明(related question)添加到程序中......
constexpr char S<42>::s[];
...它会抑制错误,程序会编译。
标准中的哪个部分指明没有这个额外声明的程序是不正确的?这里有哪些规则?
答案 0 :(得分:3)
§9.4.2/ 3:
可以使用
static
说明符在类定义中声明文字类型的constexpr
数据成员;如果是这样,它的声明应指定一个大括号或等于初始化,其中作为赋值表达式的每个 initializer-clause 是一个不断表达。 如果程序中使用了odr-used(3.2),并且名称空间范围定义不包含初始化程序,则仍应在名称空间作用域中定义该成员。
[强调补充]
在我看来,当你在main
打印出一个使用odr的值时,所以编译器是正确的:定义是必需的。