哪些规则决定一个对象是否可平凡复制
Which rules determine whether an object is trivially copyable
随着 c++11 的引入,trivially copyableness 变得非常重要。最值得注意的是 'std::atomic' 的使用。基础很简单。如果满足以下条件,class 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 可用于测试对象是否可平凡复制。因此,通过反复试验,可以使对象轻松复制。
当然,一套明确定义的规则会更好一些:)。所以特此请求。
最明确的规则集将直接来自标准。以下是标准草案 N4296 中的相关条目:
平凡可复制类型在 [basic.types]/9
中定义
Cv-unqualified scalar types, trivially copyable class types, arrays of such types, and nonvolatile
const-qualified versions of these types are collectively called trivially copyable types.
平凡可复制的 classes 在 [class]/6
中定义
A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.
Copy/move [class.copy]/12
中的构造函数
A copy/move constructor for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if class X has no virtual functions and no virtual base classes, and class X has no non-static data members of volatile-qualified type, and the constructor selected to copy/move each direct base class subobject is trivial, and for each non-static data member of X that is of class type (or array thereof), the constructor selected
to copy/move that member is trivial; otherwise the copy/move constructor is non-trivial.
Copy/move [class.copy]/25
中的赋值运算符
A copy/move assignment operator for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if class X has no virtual functions and no virtual base classes, and class X has no non-static data members of volatile-qualified type, and the assignment operator selected to copy/move each direct base class subobject is trivial, and for each non-static data member of X that is of class type (or array thereof), the assignment operator
selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is non-trivial.
[class.dtor]/5
中的析构函数
A destructor is trivial if it is not user-provided and if: the destructor is not virtual, all of the direct base classes of its class have trivial destructors, for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor. Otherwise, the destructor is non-trivial.
[dcl.fct.def.default]/5
中用户提供的构造函数
Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions,
and the implementation shall provide implicit definitions for them (12.1 12.4, 12.8), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or
deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its
first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined
as deleted, the program is ill-formed.
简短的回答是简短的回答有时比长的回答更有帮助。
随着 c++11 的引入,trivially copyableness 变得非常重要。最值得注意的是 'std::atomic' 的使用。基础很简单。如果满足以下条件,class 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 可用于测试对象是否可平凡复制。因此,通过反复试验,可以使对象轻松复制。
当然,一套明确定义的规则会更好一些:)。所以特此请求。
最明确的规则集将直接来自标准。以下是标准草案 N4296 中的相关条目:
平凡可复制类型在 [basic.types]/9
中定义Cv-unqualified scalar types, trivially copyable class types, arrays of such types, and nonvolatile const-qualified versions of these types are collectively called trivially copyable types.
平凡可复制的 classes 在 [class]/6
中定义A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.
Copy/move [class.copy]/12
中的构造函数A copy/move constructor for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if class X has no virtual functions and no virtual base classes, and class X has no non-static data members of volatile-qualified type, and the constructor selected to copy/move each direct base class subobject is trivial, and for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial; otherwise the copy/move constructor is non-trivial.
Copy/move [class.copy]/25
中的赋值运算符A copy/move assignment operator for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if class X has no virtual functions and no virtual base classes, and class X has no non-static data members of volatile-qualified type, and the assignment operator selected to copy/move each direct base class subobject is trivial, and for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial; otherwise the copy/move assignment operator is non-trivial.
[class.dtor]/5
中的析构函数A destructor is trivial if it is not user-provided and if: the destructor is not virtual, all of the direct base classes of its class have trivial destructors, for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor. Otherwise, the destructor is non-trivial.
[dcl.fct.def.default]/5
中用户提供的构造函数Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them (12.1 12.4, 12.8), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.
简短的回答是简短的回答有时比长的回答更有帮助。