簡體   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;
}

下面關於使用右值和左值引用的代碼有什么區別。

  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

問題:

  1. 右值引用(案例 2)可以保存 memory 副本嗎? 比案例1
  2. 為什么左值引用(case3)出錯但它適用於const (case4)?
  1. 當 prvalue(“臨時”)綁定到右值引用const左值引用時,臨時值的生命周期會延長到引用的生命周期。
  2. const左值引用不會延長純右值的生命周期。

右值引用(案例 2)可以保存 memory 副本嗎? 比案例1

它保留了單個返回的 object 的生命周期。 見 1。

為什么左值引用(case3)出錯

見 2。

但它適用於 const (case4)?

見 1。

  1. 右值引用(案例 2)可以保存 memory 副本嗎? 比案例1

如果您的意思是“案例 2 是否避免了案例 1 的某些副本”,那么答案是:不。如果res是自動變量,兩者實際上是相同的。 我建議編寫案例 1,因為它更簡單且不易混淆。

首先,從vec移動到返回值。 在實踐中,優化器可以忽略這一舉動。 這種優化稱為 NRVO(命名返回值優化)。

由於 C++17: 在這兩種情況下,都直接通過上述移動(可能已被省略)初始化。

Pre-C++17:在這兩種情況下,從返回值到初始化的 object 都有另一個移動。 這一舉動在實踐中也可以省略。

  1. 為什么左值引用(case3)出錯但它適用於const(case4)?

因為對非常量的左值引用可能不會綁定到右值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM