在c ++ 11中使用rvalue引用

Sam*_*yon 9 c++ rvalue-reference c++11

我想实现一个填充向量然后返回右值引用的函数.我厌倦了:

std::vector<int> &&fill_list() {
  std::vector<int> res;
  ... do something to fill res ...
  return res;
}

int main(int argc, char **argv) {
  std::vector<int> myvec = fill_list();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,我收到以下错误:

error: invalid initialization of reference of type 'std::vector<int>&&' from expression of type 'std::vector<int>'
Run Code Online (Sandbox Code Playgroud)

总而言之,正确的做法是怎样的?我认为我还没有获得右值参考.

Nic*_*las 29

你似乎对rvalue引用是什么以及它与移动语义的关系感到困惑.

第一件事是第一件事:&& 并不意味着搬家.它只不过是一种特殊的引用类型.它仍然是一个参考.这不是一个价值; 它不是一个移动的价值; 它是对价值的引用.这意味着它具有参考类型的所有限制.值得注意的是,它必须引用仍然存在的值.所以返回一个悬空的r值引用并不比返回一个悬空的l值引用更好.

"移动"是让一个对象声明对另一个对象的内容的所有权的过程.R值引用有助于移动语义,但仅仅具有一个&&并不意味着任何移动.运动发生在一个移动构造函数(或移动赋值运算符)被调用; 除非调用这两件事中的一件,否则不会发生任何动作.

如果您希望将功能的内容移动std::vector到用户,您只需执行以下操作:

std::vector<int> fill_list() {
  std::vector<int> res;
  ... do something to fill res ...
  return res;
}
Run Code Online (Sandbox Code Playgroud)

考虑到这种用法fill_list():

std::vector<int> myvec = fill_list();
Run Code Online (Sandbox Code Playgroud)

将发生两件事之一.返回将被省略,这意味着不会发生复制移动.res直接构造成myvec.或者res将被移动到返回值,然后执行移动初始化myvec.所以再一次,没有复制.

如果你有这个:

std::vector<int> myvec;
myvec = fill_list();
Run Code Online (Sandbox Code Playgroud)

然后,它将被移入.没有复制.

C++ 11知道何时隐式移动东西是安全的.通过值而不是通过引用或某种方式返回值始终是一个安全的移动时间.因此,它会移动.