为什么同时具有默认析构函数和向量成员会阻止 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。
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
的隐式复制构造函数也可能会抛出。
给定以下代码:
#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。
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
的隐式复制构造函数也可能会抛出。