【问题标题】:Move object without a move constructor在没有移动构造函数的情况下移动对象
【发布时间】:2016-12-12 11:35:16
【问题描述】:

再讲一次,但相关问题没有回答我的问题。

标准很明确:

12.8 复制和移动类对象,
§9
如果类 X 的定义没有显式声明移动构造函数,则当且仅当
— X 没有用户声明的复制构造函数,
— X 没有用户声明的复制赋值运算符,
— X 没有用户声明的移动赋值运算符,
— X 没有用户声明的析构函数,并且
— 移动构造函数不会被隐式定义为已删除。
[注意:当移动构造函数没有被隐式声明或显式提供时,否则会调用移动构造函数的表达式可能会调用复制构造函数。 ——尾注]

所以,在注意到末尾的“注释”之前,我预计这段代码会编译失败(虽然我知道,移动 应该 退回到复制):

#include <iostream>
using std::cout;
class c
{
public:
    c() { cout << "c::c()\n"; }
    c( std::initializer_list< int > ) { cout << "c::c( std::initializer_list )\n"; };

    c( const c& ) { cout << "c::c( const c& )\n"; }
    c& operator=( const c& ) { cout << "c& c::operator=( const c& )\n"; return *this; }

    ~c() { cout << "c::~c()\n"; }

    void f() {}
};

void f( c&& cr ) { cout << "f()\n"; cr.f(); }

int main()
{
    c x;
    f( std::move( x ) );

    return 0;
}

然后我看到了最后的注释,但我还是很惊讶,上面的代码输出:

c::c()
f()
c::~c()

注意“缺失”c::c( const c&amp; )。然后我添加了

c( c&& ) = delete;
c& operator=( c&& ) = delete;

结果还是一样。

我错过了什么?


$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609

编译器标志:-s -O0 -march=native -pthread -std=c++11 -Wall -Wextra -DNDEBUG。

【问题讨论】:

  • cr 是尚未被任何构造函数使用的右值 reference...
  • @W.F. - 哦,天哪,请将此作为答案发布。你非常正确。 (添加 c xx( std::move( x ) ); 而不是使用 f( c&amp;&amp; ) 会产生预期的行为。
  • 这是一个 nop 问题 XD
  • @Stargateur - “nop question”?
  • @KirilKirov en.wikipedia.org/wiki/NOP。因为你的例子没有问题:p

标签: c++ move move-constructor implicit-constructor


【解决方案1】:

你没有移动任何物体。

std::move 实际上很混乱,因为它不会移动任何东西。只有移动构造函数或移动赋值运算符可以移动对象,std::move 所做的只是将左值引用 (&amp;) 转换为右值引用(&amp;&amp;)。

移动构造函数或移动赋值运算符可以绑定到 r-value-refernce(&amp;&amp;) 并窃取对象内容。

【讨论】:

  • 这是一个非常好的解释,它完美地补充了公认的答案。 +1,谢谢
【解决方案2】:

您示例中的cr 参数是一个右值参考。参考词在这里很重要。它的行为有点类似于我们从 c++ 中知道的平面旧引用,在 c++11 出现在游戏中之前,它不调用任何构造函数……它只是“指向”你传递的对象。 ..

要调用移动构造函数(或进行其他交换)并使用引用,我们需要进一步转发引用,例如如下:

void f( c&& cr ) {
   c cr2(std::move(cr));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-30
    • 2017-09-19
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 2023-04-08
    相关资源
    最近更新 更多