为何Clang与GCC认为删除默认构造函数的s是平凡类类型?
为何Clang和GCC认为
s是平凡类类型? #include <type_traits> struct s { s() = delete; }; static_assert(not std::is_trivial_v<s>); // clang不通过, gcc不通过, msvc通过
这个差异的核心是C标准在C14版本对平凡类型的定义做了修改:
标准版本的关键差异
- C++11及更早:平凡类型必须同时满足「可平凡拷贝(trivially copyable)」和「拥有平凡默认构造函数」。按这个规则,
s的默认构造函数被删除,没有合法的平凡默认构造函数,确实不该被视为平凡类型。 - C++14及之后:平凡类型的定义调整为「可平凡拷贝」且(「拥有平凡默认构造函数」或「不可默认构造」)。
对struct s的具体分析
struct s完全符合C++14+的平凡类型判定条件:
- 可平凡拷贝:它的析构函数、拷贝/移动构造函数、拷贝/移动赋值运算符都是编译器隐式生成的平凡版本,没有用户自定义的相关函数,满足可平凡拷贝的要求。
- 不可默认构造:默认构造函数被显式删除,无法通过默认构造创建实例。
因此Clang和GCC(默认采用C14及以上标准)会判定std::is_trivial_v<s>为true,导致断言失败;而MSVC的实现未完全跟进这一标准变化,仍按C11的逻辑处理,所以断言通过。
内容的提问来源于stack exchange,提问作者303
相关产品推荐
相关产品推荐

