当前位置: 首页 > 知识库问答 >
问题:

移动构造函数是自动生成的,即使成员没有移动构造函数?

敖硕
2023-03-14

引用自C Primer

如果我们显式地要求编译器使用=默认生成移动操作,并且编译器无法移动所有成员,那么移动操作将被定义为删除

如果类有一个定义自己的复制构造函数的成员,但不定义移动构造函数,或者如果类有一个不定义自己的复制操作的成员,并且编译器无法合成,则移动构造函数被定义为删除移动构造函数

有些代码似乎违反了这条规则:

#include <utility>
#include <iostream>

struct X {
    X() = default;
    X(const X&) { std::cout << "X(const X&)" << std::endl; }
    int i;
};

struct hasX {
    hasX() = default;
    hasX(const hasX &) = delete;
    hasX(hasX &&) = default;
    X mem;
};


int main()
{
    hasX hx, hx2 = std::move(hx);  //output is X(const X&)
}

X没有定义移动构造函数,编译器不能为它合成一个。

根据上述规则,hasX的移动构造函数被删除。

但是,因为hasX的复制构造函数被删除,所以hx2=std::移动(hx)必须调用移动构造函数来输出"X(const X

那么,不是在C标准中定义的,还是仅仅是编译器实现?

我测试的编译器:VS2015和在线编译器

谢谢你的帮助!


共有1个答案

缪远
2023-03-14

你的书好像错了。复制是一种有效的移动操作,只要成员具有const type形式的复制构造函数

在你的例子中

hasX(hasX &&) = default;

可以替换为

hasX(hasX &&rhs) : mem(std::move(rhs.mem)) {}

因为这就是默认值所做的,它将很好地编译。

 类似资料:
  • 我正在读《C入门》第五版,遇到了以下问题。本书列出了将合成移动操作定义为已删除的几种情况。其中之一就是与复制构造函数不同,如果类有一个成员定义了自己的复制构造函数,但没有定义移动构造函数,或者类有一个成员没有定义自己的复制操作,并且编译器无法为其合成移动构造函数,则移动构造函数被定义为已删除。同样,移动分配也是如此。“并提供如下演示代码: 然而,对于gcc 7.2.1和clang-900.0.37

  • 我试图理解“有效现代C”中关于特殊成员函数生成的第17项,所以我尝试了一些示例,并试图对一些行为进行推理。书中说: ..当我提到移动操作move构造或移动分配一个数据成员或基类时,不能保证实际会发生移动。“Memberwise移动”实际上更像Memberwise移动请求,因为未启用移动的类型(即,对移动操作不提供特殊支持的类型,例如大多数C 98遗留类)将通过其复制操作“移动”。。。此外,不会为任

  • 操作步骤: 菜单栏: Code —> Generate —> Constructor 快捷键: Mac: command + N Windows\/Linux: Alt + Insert —> Constructor

  • 似乎一个向量会检查move构造函数是否标记为noexcept,然后再决定重新分配时是移动还是复制元素。默认的移动构造函数是否定义为noexcept?我看到了以下文档,但它没有指定这一点。http://en.cppreference.com/w/cpp/language/move_constructor 隐式声明移动构造函数 如果没有为类类型(struct,类或联合),并且以下所有都是真的:没有用户

  • 问题内容: 我注意到,使用快捷方式并选择构建器,它尝试使用每个私有属性(例如和)创建一个构造器。我记得我已经创建了没有它的项目并且可以正常工作。 在完整的logcat和构造函数之后,运行应用程序时发生错误: 具有私有财产的建设者: Logcat: 问题答案: 您的所有初始化都应使用的方法执行: 覆盖的构造函数会涉及很多繁重的工作,实际上并不是在公园散步。尽管您当然 可以 为设置一个空的构造函数,但

  • 问题内容: 我在一个Activity中有一个IntentService,当我尝试调用该服务时,它将引发此错误,我发现这很奇怪,因为如果我声明了空的构造函数。 错误: AndroidManifest.xml 活动: 问题答案: 你是一个内部阶级。如果要将其保留在内部,请将其更改为static: 您可能需要阅读不同类型的嵌套类。google的第一个链接:http : //docs.oracle.com