理解std :: move()的代码

时间:2016-03-24 17:49:01

标签: c++ c++11 vector stl

我真的想了解std :: move()函数的内在细节。

std :: move()的代码如下所述:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html#Move_Semantics

template <class T>
typename remove_reference<T>::type&&
move(T&& a)
{
    return a;
}

为什么此代码返回右值引用?该参数是类型T右值参考。 a是否计算rvalue引用指向的对象,以便将rvalue引用返回给对象?另外,为什么需要remove_reference<T>部分?

本教程还写了

  

此move()为其目标提供其参数的值,但不是   有义务保持其来源的价值。所以,对于一个向量,move()   可以合理地预期将其论证作为零容量   矢量,以避免必须复制所有元素。换句话说,移动   是一种潜在的破坏性读物。

然后据说

  

移动功能确实做得很少。所有举动都是   接受左值或右值参数,并将其作为右值返回   没有触发复制结构。

如果这被理解为,std :: move()可以首先“清空”对象(在本例中为std :: vector),然后将对象作为rvalue返回(根据C ++规范)?但是,官方的std :: move()完全按照后面的引用指定了吗?

为什么当它返回一个右值引用时,std :: move()会返回一个右值?

3 个答案:

答案 0 :(得分:8)

  

std :: move()的代码如下所述:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html#Move_Semantics

这是 2006 中提出的代码。在移动语义之前是C ++的一部分。这不是{C}中std::move的实现方式,因为语言在2006年到2011年间发生了显着。如果您想了解std::move,请查看现代实现,而不是理解描述类似但不同的旧提议。

  

为什么此代码会返回右值引用?

因为这是std::move的全部目的。拿一个参数并将其转换为右值。

询问为什么这样做就像问make_pair为什么会返回pair

  

参数是类型T右值参考。

实际上它是&#34;转发引用&#34;,这意味着它可能是左值引用或右值引用。

  

a是否评估rvalue引用所指向的对象,以便将rvalue引用返回给对象?

是的,这是参考的工作方式。

  

另外,为什么需要remove_reference<T>部分?

因为如果使用左值调用std::move,则T将推导为左值引用类型,例如int&。要确保返回类型为int&&,您首先需要删除左值引用以获取int,然后添加&&以获取右值引用int&&

答案 1 :(得分:1)

browser.driver.manage().window().setSize(1400, 900); browser.driver.manage().window().maximize(); 可以被认为是一个荣耀的演员。所有这一切都将它的类型参数(一个对象或一个表达式的结果)转换为所谓的std::move。它通过返回一个右值引用来实现。

它还考虑到这样一个事实,即推论的参数类型可能是左值,其中强制转换T实际上是左值引用 - 这就是为什么它必须从T中删除引用才能获得真实&#39 39;参数的类型。

那就是它。它实际上并没有移动任何东西,清理物体或任何种类。实际的对象修改由相应的移动构造函数或assingment操作符完成。

答案 2 :(得分:0)

void f(const my_type&);
void f(my_type&&);
my_type m;
f(m);           // calls f(const my_type&)
f(std::move(m); // calls f(my_type&&)

std::move的调用唯一的作用是确保f的参数类型是右值引用。它有f一旦有了该引用,该如何处理它。

你可以用演员做同样的事情:

f(my_type&&(m));

但在多个地方使用时,调用std::move会更清晰,更一致。