我愛學(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)用
------分隔線----------------------------
    ?分享到??
看看啦
主站蜘蛛池模板: 中文字幕无线码一区二区| 一区二区福利视频| 精品视频一区二区三区四区五区| 亚洲狠狠久久综合一区77777| 亚洲综合av一区二区三区不卡 | 亚洲av乱码一区二区三区香蕉| 一区二区三区杨幂在线观看| 亚洲色一区二区三区四区| 无码精品人妻一区二区三区中| 一区二区三区免费视频网站| 国产欧美一区二区精品仙草咪| 日韩精品乱码AV一区二区| 精品视频一区二区三区免费| 亚洲午夜日韩高清一区 | 夜夜嗨AV一区二区三区| 在线免费视频一区| 无码日本电影一区二区网站| 无码精品视频一区二区三区 | 国产福利日本一区二区三区| 国产经典一区二区三区蜜芽| 人妻体内射精一区二区三区| 国产人妖视频一区二区| 国产在线一区二区| 国产精品毛片VA一区二区三区| 国产在线精品一区二区三区直播| 中文字幕亚洲一区二区三区| 国产激情精品一区二区三区| 久久综合一区二区无码| 丝袜无码一区二区三区| 亚洲天堂一区二区| 亚洲国产成人久久综合一区 | 国产成人精品第一区二区| 亚拍精品一区二区三区| 精品亚洲av无码一区二区柚蜜| 亚洲一本一道一区二区三区| 国产一区二区久久久| 日本一区二区三区久久| 青娱乐国产官网极品一区| 东京热无码av一区二区| 久久精品亚洲一区二区| 国产乱码精品一区二区三区四川人|