我愛學(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)用
------分隔線----------------------------
    ?分享到??
看看啦
主站蜘蛛池模板: 国产一区二区女内射| 亚洲视频一区在线| 无码人妻精品一区二区三区99仓本 | 中文字幕人妻无码一区二区三区| 久久久久无码国产精品一区 | 国产自产V一区二区三区C| 中文字幕精品一区二区2021年| 亚洲av日韩综合一区在线观看| 美女视频免费看一区二区| 成人毛片一区二区| 暖暖免费高清日本一区二区三区| 国内自拍视频一区二区三区 | 国产精品高清一区二区人妖| 一区二区三区午夜视频| 一区二区三区在线看| 久久久不卡国产精品一区二区| 国产高清在线精品一区二区三区| 国模无码视频一区二区三区| 精品国产aⅴ无码一区二区| 久久高清一区二区三区| 国产精品无圣光一区二区| 精品国产免费一区二区三区香蕉 | 国语对白一区二区三区| 一色一伦一区二区三区| 亚洲日韩国产一区二区三区在线| 2020天堂中文字幕一区在线观| 看电影来5566一区.二区| 国产一区二区免费视频| 无码国产精品一区二区免费16 | 精品一区二区三区免费毛片爱 | 中文字幕精品一区二区精品| 精品人妻少妇一区二区| 一区二区乱子伦在线播放| 99精品高清视频一区二区| 在线观看视频一区二区| 国产成人一区二区三区电影网站| 国模精品一区二区三区视频 | 一本AV高清一区二区三区| 国产凹凸在线一区二区| 亚洲一区二区电影| 无码视频一区二区三区|