为什么同时拥有默认析构函数和向量成员会阻止类成为“不可抛出可移动构造函数”?

Del*_*gan 2 c++ destructor type-traits move-semantics c++17

给出以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

它输出0,这意味着该类Test不能“不移动”。但是,如果我删除其中一个~Test()m_vector那么它会返回1.

请问这个怎么解释?

作为参考,我将 clang++-7 与 C++17 一起使用。

Bri*_*ian 6

请参阅[class.copy.ctor]/8

如果类的定义X没有显式声明移动构造函数,当且仅当[省略其他条件,并且]X没有用户声明的析构函数时,非显式移动构造函数才会被隐式声明为默认值。

因此,该类Test只有复制构造函数,没有移动构造函数。任何使用Test右值初始化新Test对象的代码都会使用复制构造函数,这不是noexcept因为向量成员。如果删除向量成员,则 的复制构造函数Test将变得微不足道。