【问题标题】:Reason to use std::move on rvalue reference parameter在右值引用参数上使用 std::move 的原因
【发布时间】:2019-11-08 05:54:03
【问题描述】:

我在看一本关于用C++实现的数据结构的书,我看不懂代码sn-p,它是向量类的一部分

void push_back(object &&x) {
        //do something
        objects[size++] = std::move(x);
    }

我知道std::move返回的是对象的右值引用,但是push_back成员函数已经有了右值引用x作为参数,这里的std::move是不是没必要?

另一个问题是,如果我们有一个类对象的右值引用,如果我们想要调用移动而不是版权,我们仍然需要在其成员上使用std::move?像下面的代码:

A& operator=(A&& other) {
     member = std::move(other.member);
     return *this;
}

【问题讨论】:

  • 这里好像已经回答了stackoverflow.com/questions/28483250/…
  • OT:那是什么书? objects[size++] = std::move(x); 需要在 &objects[size] 处具有向量值类型的有效对象,这不是 push_back 应该如何工作的。向量通常使用placement new(通常是分配器的construct)在此处创建新对象,而不是赋值运算符。另请注意,如果赋值抛出(通过抛出移动赋值操作或复制赋值操作),那么size 将递增并且向量的状态将不正确。最好在下一行做size++;

标签: c++ c++11 move-semantics rvalue-reference value-categories


【解决方案1】:

这里的std::move不是没必要吗?

没有。类型和value categories 是不同的东西。

(强调我的)

每个 C++ 表达式(带有操作数、文字、变量名等的运算符)都具有 两个独立的属性:类型值类别

以下表达式是左值表达式:

变量、函数、模板参数对象的名称(因为 C++20) 或数据成员,无论类型如何,例如 std::cin 或 标准::endl。 即使变量的类型是右值引用, 由其名称组成的表达式是左值表达式;

std::move 将左值转换为右值(xvalue)。作为命名变量,x 是一个左值,std::move 将其转换为objects[size++] = std::move(x); 中的右值,然后应该使用移动赋值运算符。否则,将使用复制赋值运算符;左值不能绑定到右值引用。

如果我们想调用 move 而不是 copy right,我们还需要在其成员上使用std::move

是的,原因同上。

【讨论】:

    【解决方案2】:

    x 有一个名字,因此它是函数内部的一个左值。右值引用绑定到左值xstd::move 将其转换回传入的右值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-15
      • 1970-01-01
      • 2021-08-26
      • 2020-11-16
      • 1970-01-01
      • 2015-09-21
      • 2019-07-23
      • 1970-01-01
      相关资源
      最近更新 更多