为什么同时具有默认析构函数和向量成员会阻止 class 成为 "nothrow movable constructible"?

Why having both default destructor and vector member prevents class to be "nothrow movable constructible"?

给定以下代码:

#include <iostream>
#include <vector>
#include <type_traits>

class Test {
public:
    ~Test() = default;
    std::vector<int> m_vector;
};


int main() {
    std::cout << std::is_nothrow_move_constructible_v<Test> << std::endl;
    return 0;
}

它输出0,这意味着Test class不能被“移动”。但是,如果我删除 ~Test()m_vector 那么它 returns 1.

请问如何解释?

作为参考,我在 C++17 中使用 clang++-7。

参见[class.copy.ctor]/8

If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly declared as defaulted if and only if [other conditions omitted, and] X does not have a user-declared destructor.

因此,Test class 只有复制构造函数,没有移动构造函数。任何使用 Test 右值来初始化新的 Test 对象的代码都将使用复制构造函数,由于 vector 成员,它不是 noexcept。如果删除 vector 成员,Test 的复制构造函数将变得微不足道。

当您定义用户声明的析构函数时,class 将不会有隐式生成的移动构造函数。因此,移动将调用复制构造函数。 std::vector 的复制构造函数可能会抛出,因此 Test 的隐式复制构造函数也可能会抛出。