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

C++ 为什么未初始化的constexpr变量不是常量?,c++,c++11,gcc,constexpr,C++,C++11,Gcc,Constexpr,我不确定这是编译器错误还是我误解了constexpr: struct S{}; constexpr S s1{}; constexpr S s2; struct test{ static constexpr auto t1 = s1; static constexpr auto t2 = s2; //error here }; GCC 4.8给了我一个奇怪的错误“错误:字段初始值设定项不是常量”。s2真的不是常数吗?如果是,为什么 为了清楚起见,我实际上在我的代码中使用了一

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

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

struct test{
    static constexpr auto t1 = s1;
    static constexpr auto t2 = s2;  //error here
};
GCC 4.8给了我一个奇怪的错误“错误:字段初始值设定项不是常量”。s2真的不是常数吗?如果是,为什么


为了清楚起见,我实际上在我的代码中使用了一堆空结构(用于元编程),所以我对这个特定的示例非常感兴趣

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

隐式定义的默认构造函数执行类的初始化集,该初始化集将由用户编写的默认构造函数在没有ctor初始值设定项(12.6.2)和空复合语句的情况下为该类执行。如果用户编写的默认构造函数满足
constexpr
构造函数(7.1.5)的要求,则隐式定义的默认构造函数是
constexpr

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

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


旧答案:

Clang会发出更合理的错误消息:

main.cpp:3:13: error: default initialization of an object of const type 'const S' 
requires a user-provided default constructor
constexpr S s2;
            ^
[dcl.constexpr]/9提供了解释,甚至几乎完全是您的代码示例:

对象声明中使用的
constepr
说明符将对象声明为const。这种物体应具有 文字类型,并应初始化。(…) [示例:

-[结束示例]


对于clang,const类型为“const S”的对象的默认初始化需要一个用户提供的默认构造函数,而空结构可能不需要这个构造函数,我认为有人建议更改它的标准。我现在无法查找它(在电话上评论已经够难了),但是如果你能找到它,那么在你的答案中包含它可能是值得的。提供
constepr
默认构造函数可以在没有初始值设定项的情况下定义
s2
,就像
clang
的错误消息提示一样。有趣的是,虽然gcc接受
constexpr S()=default,clang没有(从3.6开始)。我认为clang是错误的,因为[dcl.constexpr]/4允许这种声明,[dcl.constexpr]/9只需要一个常量表达式,[expr.const]将这种情况视为任何其他
constexpr
构造函数,但实际上这意味着
constexpr S(){}
是可移植性所必需的。@Wintermute我现在有点怀疑,因为根据
[class.ctor]/5
的规定,
S
的隐式默认ctor应该是
constexpr
,所以代码应该按原样编译。@antosavin-Hmm…但是[dcl.constexpr]/9中的示例毫无意义,所以我更可能忽略了什么。我稍后会仔细看一看。@Wintermute不,这是有意义的,因为
struct pixel
包含数据成员,所以它的隐式默认构造函数不是
constexpr
struct pixel {
    int x, y;
};
constexpr pixel ur = { 1294, 1024 };// OK
constexpr pixel origin; // error: initializer missing