简体   繁体   English

关于 C++ 中的右值引用

[英]About rvalue reference in C++

std::vector<std::string> func(int num) {
  std::vector<std::string> vec;
  int sum = 0;
  for(int i = 0; i < num; i++) {
    sum +=i;
    std::string s = std::to_string(sum);
    vec.emplace_back(s);
  }
  return vec;
}

what's the difference between the code below about using rvalue and lvalue reference.下面关于使用右值和左值引用的代码有什么区别。

  std::vector<std::string> res = func(10);      // (case 1)
  std::vector<std::string> &&res = func(10);    // (case 2)
  std::vector<std::string> &res = func(10);   // I got an error!, case3
  const std::vector<std::string> &res = func(10);  // case4

Question:问题:

  1. can the rvalue reference(case 2) save a memory copy?右值引用(案例 2)可以保存 memory 副本吗? than case1比案例1
  2. why lvalue reference(case3) got an error but it work with the const (case4)?为什么左值引用(case3)出错但它适用于const (case4)?
  1. When a prvalue (a "temporary") is bound to an rvalue reference or a const lvalue reference, the lifetime of the temporary is extended to the lifetime of the reference.当 prvalue(“临时”)绑定到右值引用const左值引用时,临时值的生命周期会延长到引用的生命周期。
  2. a non- const lvalue reference does not extend the lifetime of a prvalue.const左值引用不会延长纯右值的生命周期。

can the rvalue reference(case 2) save a memory copy?右值引用(案例 2)可以保存 memory 副本吗? than case1比案例1

It preserves the lifetime of the single returned object.它保留了单个返回的 object 的生命周期。 See 1.见 1。

why lvalue reference(case3) got an error为什么左值引用(case3)出错

See 2.见 2。

but it work with the const (case4)?但它适用于 const (case4)?

See 1.见 1。

  1. can the rvalue reference(case 2) save a memory copy?右值引用(案例 2)可以保存 memory 副本吗? than case1比案例1

If you mean, "does case 2 avoid some copy that case 1 has", then the answer is: No. Both are effectively identical if res is an automatic variable.如果您的意思是“案例 2 是否避免了案例 1 的某些副本”,那么答案是:不。如果res是自动变量,两者实际上是相同的。 I recommend writing the case 1 because it is simpler and less confusing.我建议编写案例 1,因为它更简单且不易混淆。

Firstly, there is a move from vec to the returned value.首先,从vec移动到返回值。 In practice, this move can be elided by an optimiser.在实践中,优化器可以忽略这一举动。 Such optimisation is known as NRVO (Named Return Value Optimisation).这种优化称为 NRVO(命名返回值优化)。

Since C++17: The is initialised directly by the move mentioned above (which may have been elided) in both cases.由于 C++17: 在这两种情况下,都直接通过上述移动(可能已被省略)初始化。

Pre-C++17: There is another move from the return value to the initialised object in both cases. Pre-C++17:在这两种情况下,从返回值到初始化的 object 都有另一个移动。 This move can also be elided in practice.这一举动在实践中也可以省略。

  1. why lvalue reference(case3) got an error but it work with the const (case4)?为什么左值引用(case3)出错但它适用于const(case4)?

Because lvalue references to non-const may not be bound to rvalues.因为对非常量的左值引用可能不会绑定到右值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM