为何需要对对象进行花括号初始化才能使其符合constexpr要求?
你给出的示例代码如下:
template <typename T> struct MyClass { constexpr MyClass() = default; int member; }; template <typename T> constexpr MyClass<T> makeMyClass(T t) { MyClass<T> temp; // ^^^此处添加{}即可解决报错 temp.member = 3; return temp; } int main() { constexpr auto myclassobj = makeMyClass(6); // 无花括号初始化时此处会报错:error: uninitialized variable ‘temp’ in ‘constexpr’ function }
问题解答
你的默认化constexpr构造函数本身没有编写错误,不管加不加花括号初始化对象,都会调用这个constexpr构造函数,不存在调用非constexpr构造函数的情况,报错核心是初始化行为不符合constexpr上下文的要求:
- 无括号的
MyClass<T> temp;属于默认初始化,默认实现的构造函数不会对内置类型的member成员做初始化操作,此时对象处于未初始化状态。C++标准明确禁止constexpr函数的编译期求值路径中出现未初始化变量,哪怕你后续马上对成员赋值,这个未初始化的中间阶段已经违反规则,所以编译器会抛出错误。 - 加花括号的
MyClass<T> temp{};属于值初始化,会先对整个对象做零初始化,member会被初始化为0,后续对member赋值3的操作完全合法,符合constexpr上下文的要求,报错自然消失。 - 不同编译器表现不一致是因为MSVC对constexpr规则的检查宽松度更高,没有严格执行标准的未初始化校验,而GCC、Clang等编译器的检查更贴合标准要求。
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

