C++11 可平凡复制类型 (TriviallyCopyable)
可平凡复制类型
- 标量类型(算术类型/枚举/指针)
- 可平凡复制类类型 Trivially copyable class
- 可平凡复制类型的数组
- cv限定的可平凡复制类型(const/volatile)
Trivially copyable class可平凡复制类
A trivially copyable class is a class that
has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator,
- each eligible copy constructor is trivial
- each eligible move constructor is trivial
- each eligible copy assignment operator is trivial
- each eligible move assignment operator is trivial, and
- has a non-deleted trivial destructor.
Trivial class
A trivial class is a class that
- is trivially copyable, and
- has one or more eligible default constructors such that each is trivial.
#include <iostream>
using namespace std;
// trivially copyable
class A
{
~A() = default; // trivially copyable
A() {} // trivially copyable
A(const A &) = default; // trivially copyable
A(A &&) = default; // trivially copyable
A &operator=(const A &) = default; // trivially copyable
A &operator=(A &&) = default; // trivially copyable
};
class B
{
// 只要有任意自定义的下列行为即会变成 not trivially copyable
virtual void foo() = 0; // not trivially copyable
// ~B() = delete; // not trivially copyable
// ~B() {} // not trivially copyable
// B(const B &) {} // not trivially copyable
// B(B &&) {} // not trivially copyable
// B &operator=(const B &) {} // not trivially copyable
// B &operator=(B &&) {} // not trivially copyable
};
// not trivially copyable
class C : public B
{
};
// trivially copyable
class D
{
public:
explicit D(int val) : d(val) {}
int d;
};
void TriviallyCopyableTest()
{
cout << std::is_trivially_copyable<bool>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<char>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<int>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<float>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<double>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<std::nullptr_t>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<int *>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<A>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<A *>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<B>::value << endl; // not trivially copyable
cout << std::is_trivially_copyable<B *>::value << endl; // trivially copyable
cout << std::is_trivially_copyable<C>::value << endl; // not trivially copyable
cout << std::is_trivially_copyable<string>::value << endl; // not trivially copyable
}
error C2338,例子中B属于not trivially copyable class,所以不适用于atomic模板
class B
{
virtual void foo() = 0; // not trivially copyable
// ~B() = delete; // not trivially copyable
// ~B() {} // not trivially copyable
// B(const B &) {} // not trivially copyable
// B(B &&) {} // not trivially copyable
// B &operator=(const B &) {} // not trivially copyable
// B &operator=(B &&) {} // not trivially copyable
};
std::atomic<B> b;
error C2338: static_assert failed: 'atomic
requires T to be trivially copyable, copy constructible, move constructible, copy assignable, and move assignable.'
参考
https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable
https://en.cppreference.com/w/cpp/language/cv
https://en.cppreference.com/w/cpp/named_req/ScalarType
https://en.cppreference.com/w/cpp/language/classes#Trivially_copyable_class