【问题标题】:Explicitly deleted move constructor显式删除的移动构造函数
【发布时间】:2018-03-26 18:18:47
【问题描述】:

为什么会这样:

struct A
{
    A(int) {
        cout << "construct from int" << endl;
    }

    A(A&&) = delete;

    A(const A &) {
        cout << "copy constructor" << endl;
    }
};

int main(){
    A a = 0;
}

给我一​​个错误:

error: use of deleted function ‘A::A(A&&)’

以及为什么当我添加这样的移动构造函数时

A(A&&) {
    cout << "move constructor" << endl;
}

它编译得很好,但程序的输出只是

construct from int

据我所知,编译器要求构造函数但不使用它。为什么?这对我来说毫无意义。

附:我认为

A a = 0;

等价于

A a = A(0);

但是为什么不调用移动构造函数和移动赋值运算符呢?

【问题讨论】:

  • 你使用的是哪个编译器?
  • 这在 C++17 中有所改变(删除的移动构造函数现在可以编译),但复制/移动省略始终是在那之前的事情。
  • 我在 g++4.9、g++6.3 和 clang 5.0 上都试过了。 (-O0 -std=c++11)
  • 确实,使用 -std=c++17 在 clang 5 上编译
  • 现在请教一些不请自来的建议:youtube.com/watch?v=vLinb2fgkHk&t=55m51s

标签: c++ c++11 constructor copy-constructor


【解决方案1】:

根据 C++ 标准(12.8 复制和移动类对象)

31 当满足某些条件时,允许省略实现 类对象的复制/移动构造,即使构造函数 选择用于复制/移动操作和/或析构函数 对象有副作用。在这种情况下,实施将 省略的复制/移动操作的源和目标只是两个 引用同一对象的不同方式,以及 该对象发生在两个对象的较晚时间 没有优化就会被破坏。 122 复制/移动操作,称为复制省略,在 以下情况(可以结合起来消除多个 副本): …… — 当一个临时类对象没有绑定到一个引用时 (12.2)将被复制/移动到具有相同的类对象 cv-unqualified 类型,复制/移动操作可以省略 将临时对象直接构造到 省略复制/移动

30 如果复制/移动构造函数或 对象的复制/移动赋值运算符是隐式使用的,并且 特殊成员函数不可访问(第 11 条)。 [ 笔记: 使用复制/移动构造函数将一个对象复制/移动到另一个对象 或复制/移动赋值运算符不改变布局或 任一对象的大小。 ——尾注]

【讨论】:

  • 我觉得这个标准很难理解,你能给出一些解释或示例代码吗?
  • @HảiPhạmLê 看粗体字就够了。问题中给出了示例代码。
猜你喜欢
  • 2014-03-19
  • 2011-10-09
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 2019-10-08
  • 1970-01-01
相关资源
最近更新 更多