我愛學(xué)習(xí)網(wǎng)-上傳
當(dāng)前位置: 主頁 > 文庫 > C++ >

c++ 引用折疊

時間:2020-11-09 20:12來源:我愛學(xué)習(xí)網(wǎng) 作者:apple 點擊:

引用折疊

在現(xiàn)代 C++ 中一共有兩種引用類型,左值引用與右值引用,因此,在類型組合與推導(dǎo)的時候它們可能會出現(xiàn)四種組合。但是 C++ 不允許出現(xiàn)引用的引用,因此,需要一種機制來消除多重引用,這個機制就是引用折疊,引用折疊規(guī)則如下:

補充幾點:

  1. 引用折疊是針對通用引用的
  2. 當(dāng)左值作為參數(shù)傳入的時候模板參數(shù) T 推導(dǎo)為左值引用類型 T&
  3. 當(dāng)右值作為參數(shù)傳入的時候模板參數(shù) T 推導(dǎo)為值類型 T
  4. 然后再應(yīng)用引用折疊規(guī)則,推導(dǎo)出具體的參數(shù)類型

引用折疊使用場景

引用折疊發(fā)生的場景不多,主要有下面四種情形:

  1. T&& 模板類型推導(dǎo)
  2. auto&& 變量類型推導(dǎo),包括 Lambda 形參
  3. typedef / using T&& 別名聲明
  4. decltype(T)

代碼示例 :

#include 

class X {};

// lvalues are encoded as lvalue reference type
// rvalues are encoded as non-reference value type
// T's type plus '&&' collapse to param's type
template  void func(T &?m) {
  if constexpr (std::is_lvalue_reference_v) {
    std::cout << "T is lvalue reference\n";
    // T deduced to 'T&'
    // param's type is 'T& &&' collapse to 'T&'
  } else {
    std::cout << "T is non-reference\n";
    // T deduced to 'T'
    // param's type is 'T &&' collapse to 'T&&'
  }
}

template  class Y {
public:
  typedef T &&rvalueRef_t0;
  using rvalueRef_t1 = T &&;
  rvalueRef_t1 y_;
};

int main() {
  std::cout << std::boolalpha;
  using std::cout, std::is_same_v;

  // case 1: template instantiation (T&&)
  X x1{};
  func(x1);            // T is lvalue reference
  func(std::move(x1)); // T is non-reference

  // case 2: auto&& variable
  X x20{};
  // lvalue cause auto deduced to 'X&'
  // x21's type is 'X& &&' collapse to 'X&'
  auto &&x21 = x20;
  cout << is_same_v << '\n'; // true

  // rvalue cause auto deduced to 'X'
  // x22's type is 'X &&' collapse to 'X&&'
  auto &&x22 = std::move(x20);
  cout << is_same_v << '\n'; // true

  // case 3: typedef and alias declarations
  cout << is_same_v::rvalueRef_t0> << '\n';   // true
  cout << is_same_v::rvalueRef_t1> << '\n';   // true
  cout << is_same_v::rvalueRef_t0> << '\n'; // true
  cout << is_same_v::rvalueRef_t1> << '\n'; // true

  // case 4: decltype
  cout << is_same_v::y_)> << '\n'; // true

  return 0;
}

再談 std::forward

圖解 std::forward 與引用折疊的工作過程:

std::forward 對于左值,返回左值引用,對于右值,返回右值引用,保留類型修飾符

總結(jié)

  1. 理解引用折疊規(guī)則
  2. 了解引用折疊發(fā)生的場景
  3. 理解完美轉(zhuǎn)發(fā)的本質(zhì),以及引用折疊規(guī)則的應(yīng)用
------分隔線----------------------------
    ?分享到??
看看啦
主站蜘蛛池模板: 在线精品视频一区二区| 亚洲成AV人片一区二区密柚| 中文无码AV一区二区三区| 亚洲综合无码一区二区| 夜色阁亚洲一区二区三区| 亚洲色偷精品一区二区三区| 亚洲一区无码精品色| 国产免费一区二区三区VR| 欧美日韩综合一区二区三区| 蜜臀AV一区二区| 人妻激情偷乱视频一区二区三区| 国产亚洲欧洲Aⅴ综合一区| 日韩一区二区三区视频久久| 人妻体内射精一区二区三区| 久久se精品一区二区| 国产精品一区二区av| 果冻传媒一区二区天美传媒| 精品乱码一区二区三区在线| 国产福利一区二区精品秒拍| 亚洲欧洲日韩国产一区二区三区 | 亚洲国产系列一区二区三区| 夜夜嗨AV一区二区三区 | 日本香蕉一区二区三区| 亚洲综合在线一区二区三区| 国产品无码一区二区三区在线| 亚洲国产成人久久综合一区| 骚片AV蜜桃精品一区| 国产日本亚洲一区二区三区| 中文字幕在线不卡一区二区| 性盈盈影院免费视频观看在线一区| 人妻av综合天堂一区| 精品女同一区二区三区免费播放| 国产精品电影一区二区三区| 亚洲片一区二区三区| 亚洲中文字幕无码一区| 色窝窝无码一区二区三区| 91视频国产一区| 欧洲精品码一区二区三区免费看| 亚洲一区二区精品视频| 免费无码一区二区三区蜜桃| 秋霞无码一区二区|