随着c ++ 11的引入,trivially copyableness变得非常重要。最值得注意的是使用'std :: atomic'。基础很简单。如果符合以下条件,则foo
类可以轻松复制:
foo* src = new foo();
foo* dest = malloc(sizeof(foo));
memcpy(dest, src, sizeof(foo));
具有与以下相同的效果:
foo* src = new foo();
foo* dest = new foo(src);
因此复制内存的对象与复制构造函数具有相同的效果。然而,当然,这是一个问题。不仅有复制构造函数。但也移动构造函数,移动赋值运算符。等
std::is_trivially_copyable可用于测试对象是否可以轻易复制。因此,通过反复试验,可以使对象易于复制。
但当然一套定义明确的规则会更好一些:)。所以我的要求。
答案 0 :(得分:14)
最明确的规则集将直接来自标准。以下是标准草案N4296的相关条目:
平凡可复制的类型在 [basic.types] / 9
中定义Cv不合格的标量类型,简单的可复制类类型,此类型的数组和非易失性 这些类型的const限定版本统称为平易可复制的类型。
平凡可复制的课程在 [class] / 6
中定义一个简单的可复制类是一个类:没有非平凡的复制构造函数,没有非平凡的移动构造函数,没有非平凡的复制赋值运算符,没有非平凡的移动赋值运算符,并且有一个简单的析构函数。
在 [class.copy] / 12
中复制/移动构造函数如果不是用户提供的,则类X的复制/移动构造函数是微不足道的,其参数类型列表等效于隐式声明的参数类型列表,并且如果类X没有虚函数,没有虚拟基类,并且类X没有volatile限定类型的非静态数据成员,并且选择用于复制/移动每个直接基类子对象的构造函数是微不足道的,并且对于X的每个非静态数据成员是类类型(或其数组),选择的构造函数 复制/移动该成员是微不足道的;否则复制/移动构造函数是非常重要的。
在 [class.copy] / 25
中复制/移动作业运算符如果不是用户提供的,则类X的复制/移动赋值运算符是微不足道的,其参数类型列表等效于隐式声明的参数类型列表,并且如果类X没有虚函数并且没有虚拟基类,并且类X没有volatile限定类型的非静态数据成员,并且选择用于复制/移动每个直接基类子对象的赋值运算符是微不足道的,并且对于X的每个非静态数据成员是类类型(或其数组),赋值运算符 选择复制/移动该成员是微不足道的; 否则复制/移动赋值运算符是非常重要的。
[class.dtor] / 5
中的析构函数如果析构函数不是用户提供的,并且如果:析构函数不是虚拟的,则析构函数是微不足道的,其类的所有直接基类都具有简单的析构函数,对于其类的所有非静态数据成员类类型(或其数组),每个这样的类都有一个简单的析构函数。否则,析构函数是非常重要的。
用户提供的构造函数 [dcl.fct.def.default] / 5
明确默认的函数和隐式声明的函数统称为默认函数, 并且实现应为它们提供隐式定义(12.1 12.4,12.8),这可能意味着将它们定义为已删除。如果函数是用户声明的,并且未明确默认,则用户提供该函数 在第一份声明中删除。用户提供的显式默认功能(即,在其后明确默认) 第一个声明)是在明确默认的地方定义的;如果隐含地定义了这样的函数 如删除,该程序是不正确的。
简短的回答是简短的回答有时比长回答更有帮助。