为什么未初始化的constexpr变量不是常数?

odi*_*erd 6 c++ gcc constexpr c++11

我不确定这是编译器错误还是我误解了constexpr:

struct S{};
constexpr S s1{};
constexpr S s2;

struct test{
    static constexpr auto t1 = s1;
    static constexpr auto t2 = s2;  //error here
};
Run Code Online (Sandbox Code Playgroud)

GCC 4.8给我一个奇怪的错误"错误:字段初始化程序不是常数".s2真的不是常数吗?如果是这样的话?

为清楚起见,我实际上在我的代码中使用了一堆空结构(对于元编程https://github.com/porkybrain/Kvasir),所以我真的对这个具体的例子很感兴趣.

Ant*_*vin 5

更新:代码应该编译,因为[class.ctor]/5读取:

\n\n
\n

隐式定义的默认构造函数执行类的一组初始化,这些初始化将由用户编写的该类的默认构造函数执行,没有构造函数初始化程序(12.6.2) 和空的复合语句。如果用户编写的默认构造函数满足构造函数(7.1.5)的要求constexpr,则隐式定义的默认构造函数是constexpr

\n
\n\n

由于S它只是一个空结构,因此隐式定义的默认构造函数是空的,因此满足constexpr要求。

\n\n

所以在这里你要处理编译器的缺陷,你必须以某种方式解决它。

\n\n
\n\n

旧答案:

\n\n

Clang 发出更明智的错误消息:

\n\n
main.cpp:3:13: error: default initialization of an object of const type 'const S' \nrequires a user-provided default constructor\nconstexpr S s2;\n            ^\n
Run Code Online (Sandbox Code Playgroud)\n\n

[dcl.constexpr]/9 提供了解释,甚至几乎完全是您的代码作为示例:

\n\n
\n

对象声明中使用的说明符constexpr将该对象声明为 const。这样的对象应具有\n 文字类型并应进行初始化。(...)\n [示例:

\n
\n\n
struct pixel {\n    int x, y;\n};\nconstexpr pixel ur = { 1294, 1024 };// OK\nconstexpr pixel origin; // error: initializer missing\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

\xe2\x80\x94end 示例]

\n
\n