C++11中std:move()的作用和用法

官方文档:http://www.cplusplus.com/reference/utility/move/?kw=move

功能:返回传入参数的右值引用。右值引用的概念是在C++11才提出来的。在此之前只有一种引用。

优点:调用此函数不会引起任何数据争用。(Calling this function introduces no data races.)

说明:

This is a helper function to force move semantics on values, even if they have a name: Directly using the returned value causes arg to be considered an rvalue.

Generally, rvalues are values whose address cannot be obtained by dereferencing them, either because they are literals or because they are temporary in nature (such as values returned by functions or explicit constructor calls). By passing an object to this function, an rvalue that refers to it is obtained.

Many components of the standard library implement move semantics, allowing to transfer ownership of the assets and properties of an object directly without having to copy them when the argument is an rvalue.

Although note that -in the standard library- moving implies that the moved-from object is left in a valid but unspecified state. Which means that, after such an operation, the value of the moved-from object should only be destroyed or assigned a new value; accessing it otherwise yields an unspecified value.

通常,右值是其地址无法通过解引用获得的值,因为它们是文字或本质上是临时的(例如,函数或显式构造函数返回的值)。 通过将对象传递给此函数,可以获得引用该对象的右值。

标准库的许多组件都实现了移动语义,允许直接转移对象的资产和属性的所有权,而在参数为右值时无需复制它们。

要注意-在标准库中-移动意味着从中移出的对象处于有效但未指定的状态。 这意味着在执行此操作后,仅应销毁移出对象的值或为其分配新值; 否则访问它会产生未指定的值。

看例子代码:

// move example
#include <utility>      // std::move
#include <iostream>     // std::cout
#include <vector>       // std::vector
#include <string>       // std::string

int main () {
  std::string foo = "foo-string";
  std::string bar = "bar-string";
  std::vector<std::string> myvector;

  myvector.push_back (foo);                    // copies
  myvector.push_back (std::move(bar));         // moves

  std::cout << "myvector contains:";
  for (std::string& x:myvector) std::cout << ' ' << x;
  std::cout << '\n';
  
  std::cout << "foo:"<<foo<<'\n';
  std::cout << "bar:"<<bar<<std::endl;

  return 0;
}

输出结果如下:

myvector contains: foo-string bar-string
foo:foo-string
bar:

看到move的作用了吧.

看看如果不用std::move()对比一下:

// move example
#include <utility>      // std::move
#include <iostream>     // std::cout
#include <vector>       // std::vector
#include <string>       // std::string

int main () {
  std::string foo = "foo-string";
  std::string bar = "bar-string";
  std::vector<std::string> myvector;

  myvector.push_back (foo);                    // copies
  myvector.push_back (bar);         // moves

  std::cout << "myvector contains:";
  for (std::string& x:myvector) std::cout << ' ' << x;
  std::cout << '\n';
  
  std::cout << "foo:"<<foo<<'\n';
  std::cout << "bar:"<<bar<<std::endl;

  return 0;
}

输出结果如下:

myvector contains: foo-string bar-string
foo:foo-string
bar:bar-string

参考中对于这个例子的解释:

The first call to myvector.push_back copies the value of foo into the vector (foo keeps the value it had before the call).
The second call moves the value of bar into the vector. This transfers its content into the vector (while bar loses its value, and now is in a valid but unspecified state).

第一次调用myvector.push_back会将foo的值复制到向量中(foo保留调用前的值)。
第二次调用将bar的值移动到向量中。 这会将其内容传输到向量中(而bar失去其值,并且现在处于有效但未指定的状态)。

猜你喜欢

转载自blog.csdn.net/grf123/article/details/105379337