C++11 可平凡复制类型 (TriviallyCopyable)

可平凡复制类型

  1. 标量类型(算术类型/枚举/指针)
  2. 可平凡复制类类型 Trivially copyable class
  3. 可平凡复制类型的数组
  4. 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

posted @ 2023-07-24 21:32  BuzzWeek  阅读(534)  评论(0编辑  收藏  举报