You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20中无默认构造函数类模板代码编译分歧:哪个编译器正确?

该C++20程序是否合规?编译器行为分析

测试代码

struct not_default_constructible { not_default_constructible() = delete; };
template<typename T> struct C
{
    static constexpr T t{};
};
template<class T>
struct myClass {
    C<T> new_t() { return {}; }
};

int main() {
    myClass<not_default_constructible> d;
    d.new_t();    
}

编译情况

  • GCC、Clang在C17和C20模式下均可正常编译
  • MSVC在C++20模式下编译失败,报错信息如下:
<source>(6): error C2131: expression did not evaluate to a constant
<source>(6): note: failure was caused by call of undefined function or one not declared 'constexpr'
<source>(6): note: see usage of 'not_default_constructible::not_default_constructible'
<source>(15): note: see reference to class template instantiation 'C<T>' being compiled
        with
        [
            T=not_default_constructible
        ]

标准合规性分析

在C++20标准中,static constexpr成员的初始化规则有明确规定:当constexpr静态数据成员的初始化表达式是聚合初始化(此处的T{}属于空聚合初始化),且目标类型T是无成员的聚合类型时,该初始化操作不需要调用T的默认构造函数——因为聚合初始化是直接完成对象初始化(无成员时仅完成对象的内存构造),不会触发默认构造函数的调用流程。

not_default_constructible属于无成员的聚合类型,即使它的默认构造函数被删除,空聚合初始化T{}依然是合法的。MSVC错误地将该初始化判定为需要调用被删除的默认构造函数,这不符合C++20标准的要求。

结论:GCC和Clang的行为符合C++20标准,MSVC的行为不符合标准。

内容的提问来源于stack exchange,提问作者user20562802

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:55:20