为何带volatile T转T构造的非volatile T类型被认定为非平凡类型?
为什么带volatile拷贝构造函数的struct T会被认定为非平凡类型?
struct T { int a; T() = default; T(const T &) = default; T(const volatile T &src) { a = src.a; } };
问题背景
如果不提供接受const volatile T&参数的拷贝构造函数,T是平凡类型;一旦添加这个自定义构造函数,T就不再是平凡类型。我们能理解volatile T是非平凡类型,但疑惑为什么非volatile的T仅仅因为这个自定义构造函数就失去了平凡类型的属性?
核心原因
C++标准对平凡类型的判定有严格要求:一个类型要成为平凡类型,必须满足所有拷贝/移动构造函数、拷贝/移动赋值运算符都是编译器自动生成的平凡版本,同时析构函数也得是平凡的。
你手动定义的T(const volatile T&)属于用户提供的构造函数——哪怕它的逻辑和默认生成的完全一致,也打破了“所有拷贝构造行为都是编译器自动生成”这个前提。只要类型中存在任何一个用户自定义的拷贝构造函数(不管它处理的是volatile还是普通cv限定的对象),整个类型就不符合平凡类型的判定标准。
从底层设计逻辑来说,标准这么规定是因为:用户提供自定义拷贝逻辑时,编译器无法确定你是否隐含了特殊操作(比如对volatile变量的访问可能需要内存屏障、特殊指令等),因此不能将该类型视为可以用memcpy这类原始内存拷贝操作来处理的平凡类型。
内容的提问来源于stack exchange,提问作者Home of the Brave
相关产品推荐
相关产品推荐

