哪些规则确定对象是否可以轻易复制

lau*_*svr 12 c++ move c++11

随着c ++ 11的引入,简单的可复制性已经变得非常相关.最值得注意的是使用'std :: atomic'.基础很简单.如果出现以下情况,课程foo可以轻易复制:

foo* src = new foo();
foo* dest = malloc(sizeof(foo));
memcpy(dest, src, sizeof(foo));
Run Code Online (Sandbox Code Playgroud)

具有相同的效果:

foo* src = new foo();
foo* dest = new foo(src);
Run Code Online (Sandbox Code Playgroud)

因此,复制内存的对象与复制构造函数具有相同的效果.然而,当然,这是一个问题.不仅有复制构造函数.但也移动构造函数,移动赋值运算符.等等.

std :: is_trivially_copyable可用于测试对象是否可以轻易复制.因此,通过反复试验,可以使对象易于复制.

但当然,一套定义明确的规则会更好一些:).所以我的要求.

Tar*_*ama 16

最明确的规则集将直接来自标准.以下是标准草案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),这可能意味着将它们定义为已删除.如果函数是用户声明的,并且在第一个声明中未明确默认或删除,则用户提供该函数.用户提供的显式默认函数(即,在第一次声明后显式默认)是在明确默认的位置定义的; 如果将这样的函数隐式定义为已删除,则该程序格式错误.

简短的回答是简短的回答有时比长回答更有帮助.