带有声明的析构函数的自动生成的默认移动构造函数
Autogenerated default move constructor with declared destructor
C++11 标准指定不应为 类 声明的析构函数生成自动生成的移动构造函数,但以下
代码片段构建并正确运行:
#include <iostream>
class C
{
public:
~C() { std::cout << "Called C:~C" << std::endl; }
private:
std::string v;
};
int main()
{
C c1;
C c2 = std::move(c1);
return 0;
}
我可以使用 clang
4.2.1 和 gcc
4.4.3 进行构建。我错过了什么吗?
初始化使用隐式定义的copy构造函数。一般来说,当移动构造函数或移动赋值运算符由于某种原因不能使用时,移动总是回退到副本,因为复制构造函数和复制赋值运算符总是声明的(尽管在某些情况下可以删除它们)。
Brian 的回答已经解释了为什么您的代码可以编译。要正确检查 move ctor 是否被抑制,只需将不可复制的对象放入您的 class,例如 std::unique_ptr
:
class C
{
public:
~C() { std::cout << "Called C:~C" << std::endl; }
private:
std::string v;
std::unique_ptr<char> p;
};
现在 gcc 5.1.0 产生这个错误:
error: use of deleted function ‘C::C(const C&)’
C c2 = std::move(c1);
C++11 标准指定不应为 类 声明的析构函数生成自动生成的移动构造函数,但以下 代码片段构建并正确运行:
#include <iostream>
class C
{
public:
~C() { std::cout << "Called C:~C" << std::endl; }
private:
std::string v;
};
int main()
{
C c1;
C c2 = std::move(c1);
return 0;
}
我可以使用 clang
4.2.1 和 gcc
4.4.3 进行构建。我错过了什么吗?
初始化使用隐式定义的copy构造函数。一般来说,当移动构造函数或移动赋值运算符由于某种原因不能使用时,移动总是回退到副本,因为复制构造函数和复制赋值运算符总是声明的(尽管在某些情况下可以删除它们)。
Brian 的回答已经解释了为什么您的代码可以编译。要正确检查 move ctor 是否被抑制,只需将不可复制的对象放入您的 class,例如 std::unique_ptr
:
class C
{
public:
~C() { std::cout << "Called C:~C" << std::endl; }
private:
std::string v;
std::unique_ptr<char> p;
};
现在 gcc 5.1.0 产生这个错误:
error: use of deleted function ‘C::C(const C&)’ C c2 = std::move(c1);