我是如何误解关于“可简单复制”的 C++ 标准的?

AIL*_*ien 8 c++ language-lawyer

下面代码中的静态断言失败。

当然,我知道这是因为 Bar 中用户提供的移动构造函数。

#include <type_traits>

using namespace std;

struct Bar
{
public:
    Bar()               = default;
    Bar(const Bar&)     = default;
    ~Bar()              = default;

    Bar(Bar&&)
    {
    }
};

struct Foo
{
    Bar b;

    Foo()                           = default;
   ~Foo()                           = default;
    Foo(const Foo&)                 = default;
    Foo(Foo&&)                      = delete;
    Foo & operator= (Foo && )       = delete;
    Foo & operator= (const Foo & )  = delete;
};


static_assert(is_trivially_copyable_v<Foo>);  // Fails

Run Code Online (Sandbox Code Playgroud)

我不明白的是如何解释关于平凡可复制性的标准。来自 C++ 17 标准:

一个简单可复制的类是一个类:

(6.1) 其中每个复制构造函数、移动构造函数、复制赋值运算符和移动赋值运算符 ([class.copy], [over.ass]) 被删除或微不足道,

(6.2) 至少有一个未删除的复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符,并且

(6.3) 有一个简单的、未删除的析构函数。

在我看来,Foo 符合以下标准:

6.1:除了微不足道的复制构造函数之外,它们都被删除了。Bar 也有一个平凡的复制构造函数,所以应该确保 Foo 复制构造函数是真正平凡的。

6.2:默认的复制构造函数

6.3: Foo 析构函数是默认的,Bar 也是默认的,所以析构函数应该是微不足道的。

我没有得到什么?

顺便说一句,除了更好地理解标准之外,我实际上并没有尝试做任何事情。

小智 0

(6.1) 其中每个复制构造函数、移动构造函数、复制赋值运算符和移动赋值运算符 ([class.copy], [over.ass]) 要么被删除,要么变得微不足道。

用户定义的构造函数并不简单。因此,您的用户定义的移动构造函数使您的对象变得不平凡。

更多内容请参见:C++ 中的非平凡构造函数是什么?

  • 这并没有在讨论中添加新的东西。您正在谈论 Bar 类,但这里的焦点是 Foo 类。问题是,为什么 Foo 被删除的移动构造函数似乎仍然相关。 (2认同)