C++17标准中哪条款规定含默认成员初始化器的类为非平凡类?
C++17中带默认成员初始化器的类为何是非平凡类?
咱们先看你给出的这段验证代码,它确实能在GCC和Clang(开启-std=c++17)下正常编译,准确区分了平凡类与非平凡类:
#include <type_traits> struct Trivial { int a; int b; }; struct NotTrivial { int a; int b{0}; }; static_assert(std::is_trivial_v<Trivial>, ""); static_assert(!std::is_trivial_v<NotTrivial>, ""); int main() {}
针对你问的“C17标准中哪一章节规定NotTrivial属于非平凡类”,咱们结合N4659(2017年3月C17 DIS)的标准条款来拆解:
1. 平凡类的定义([class]/6)
首先得明确平凡类的判定标准:
一个类是平凡类,当且仅当它满足以下所有条件:
- 没有用户声明的构造函数
- 没有用户提供的析构函数
- 没有用户提供的拷贝/移动构造函数
- 没有用户提供的拷贝/移动赋值运算符
- 所有非静态数据成员都是平凡类型
- 没有虚函数,也没有虚基类
- 所有基类都是平凡类
- 所有非静态数据成员的类类型(如果有的话)都是平凡类
2. 默认成员初始化器对默认构造函数平凡性的影响([class.default.ctor]/5)
NotTrivial类的核心问题在于,它的非静态数据成员b带有默认成员初始化器,这会导致编译器生成的默认构造函数非平凡:
如果类没有用户声明的默认构造函数,编译器会生成一个默认构造函数。但这个生成的默认构造函数是平凡的,当且仅当:
- 类的每个非静态数据成员都有默认成员初始化器,并且
- 每个基类都有默认构造函数,并且
- 每个非静态数据成员的类类型(如果有的话)都有默认构造函数
你的NotTrivial类里,成员a没有默认成员初始化器,所以编译器生成的默认构造函数不符合“平凡”的要求。而平凡类要求不能有非平凡的默认构造函数,因此NotTrivial自然不属于平凡类。
内容的提问来源于stack exchange,提问作者dfrib
相关产品推荐
相关产品推荐

