最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11 模板參數(shù)的“右值引用”是轉(zhuǎn)發(fā)引用嗎

 更新時(shí)間:2020年05月25日 14:37:20   作者:jerry_fuyi  
這篇文章主要介紹了C++11 模板參數(shù)的“右值引用”是轉(zhuǎn)發(fā)引用嗎,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在C++11中,&&不再只有邏輯與的含義,還可能是右值引用:

void f(int&& i);

但也不盡然,&&還可能是轉(zhuǎn)發(fā)引用:

template<typename T>
void g(T&& obj);

“轉(zhuǎn)發(fā)引用”(forwarding reference)舊稱“通用引用”(universal reference),它的“通用”之處在于你可以拿一個(gè)左值綁定給轉(zhuǎn)發(fā)引用,但不能給右值引用:

void f(int&& i) { }

template<typename T>
void g(T&& obj) { }

int main()
{
  int n = 2;
  f(1);
// f(n); // error
  g(1);
  g(n);
}

一個(gè)函數(shù)的參數(shù)要想成為轉(zhuǎn)發(fā)引用,必須滿足:

  • 參數(shù)類型為T&&,沒有const或volatile;
  • T必須是該函數(shù)的模板參數(shù)。

換言之,以下函數(shù)的參數(shù)都不是轉(zhuǎn)發(fā)引用:

template<typename T>
void f(const T&&);
template<typename T>
void g(typename std::remove_reference<T>&&);
template<typename T>
class A
{
  template<typename U>
  void h(T&&, const U&);
};

另一種情況是auto&&變量也可以成為轉(zhuǎn)發(fā)引用:

auto&& vec = foo();

所以寫范圍for循環(huán)的最好方法是用auto&&:

std::vector<int> vec;
for (auto&& i : vec)
{
  // ...
}

有一個(gè)例外,當(dāng)auto&&右邊是初始化列表,如auto&& l = {1, 2, 3};時(shí),該變量為std::initializer_list<int>&&類型。

轉(zhuǎn)發(fā)引用,是用來轉(zhuǎn)發(fā)的。只有當(dāng)你的意圖是轉(zhuǎn)發(fā)參數(shù)時(shí),才寫轉(zhuǎn)發(fā)引用T&&,否則最好把const T&和T&&寫成重載(如果需要的話還可以寫T&,還有不常用的const T&&;其中T是具體類型而非模板參數(shù))。

轉(zhuǎn)發(fā)一個(gè)轉(zhuǎn)發(fā)引用需要用std::forward,定義在<utility>中:


調(diào)用g有幾種可能的參數(shù):

  • int i = 1; g(i);,T為int&,調(diào)用g(int&);
  • const int j = 2; g(j);,T為const int&,調(diào)用g(const int&);
  • int k = 3; g(std::move(k));或g(4);,T為int(不是int&&哦?。?,調(diào)用g(int&&)。

你也許會(huì)疑惑,為什么std::move不需要<T>而std::forward需要呢?這得從std::forward的簽名說起:

template<typename T>
constexpr T&& forward(std::remove_reference_t<T>&) noexcept;
template<typename T>
constexpr T&& forward(std::remove_reference_t<T>&&) noexcept;

調(diào)用std::forward時(shí),編譯器無法根據(jù)std::remove_reference_t<T>反推出T,從而實(shí)例化函數(shù)模板,因此<T>需要手動(dòng)指明。

但是這并沒有從根本上回答問題,或者可以進(jìn)一步引出新的問題——為什么std::forward的參數(shù)不定義成T&&呢?

原因很簡(jiǎn)單,T&&會(huì)把T&、const T&、T&&和const T&&(以及對(duì)應(yīng)的volatile)都吃掉,有了T&&以后,再寫T&也沒用。

且慢,T&&參數(shù)在傳入函數(shù)是會(huì)匹配到T&&嗎?

#include <iostream>
#include <utility>

void foo(int&)
{
  std::cout << "int&" << std::endl;
}

void foo(const int&)
{
  std::cout << "const int&" << std::endl;
}

void foo(int&&)
{
  std::cout << "int&&" << std::endl;
}

void bar(int&& i)
{
  foo(i);
}

int main()
{
  int i;
  bar(std::move(i));
}

不會(huì)!程序輸出int&。在函數(shù)bar中,i是一個(gè)左值,其類型為int的右值引用。更直接一點(diǎn),它有名字,所以它是左值。

因此,如果std::forward沒有手動(dòng)指定的模板參數(shù),它將不能區(qū)分T&和T&&——那將是“糟糕轉(zhuǎn)發(fā)”,而不是“完美轉(zhuǎn)發(fā)”了。

最后分析一下std::forward的實(shí)現(xiàn),以下代碼來自libstdc++:

template<typename _Tp>
 constexpr _Tp&&
 forward(typename std::remove_reference<_Tp>::type& __t) noexcept
 { return static_cast<_Tp&&>(__t); }

template<typename _Tp>
 constexpr _Tp&&
 forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
 {
  static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
         " substituting _Tp is an lvalue reference type");
  return static_cast<_Tp&&>(__t);
 }

  • 當(dāng)轉(zhuǎn)發(fā)引用T&& obj綁定左值int&時(shí),匹配第一個(gè)重載,_Tp即T為int&,返回類型_Tp&&為int&(引用折疊:& &、& &&、&& &都折疊為&,只有&& &&折疊為&&);
  • const int&同理;
  • 當(dāng)轉(zhuǎn)發(fā)引用綁定右值int&&時(shí),匹配第二個(gè)重載,_Tp為int,返回類型為int&&;
  • const int&&同理。

綜上,std::forward能完美轉(zhuǎn)發(fā)。

程序員總是要在Stack Overflow上撞撞墻才能學(xué)會(huì)一點(diǎn)東西。

到此這篇關(guān)于C++11 模板參數(shù)的“右值引用”是轉(zhuǎn)發(fā)引用嗎的文章就介紹到這了,更多相關(guān)C++11 右值引用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt MQTT開發(fā)環(huán)境搭建的實(shí)現(xiàn)示例

    Qt MQTT開發(fā)環(huán)境搭建的實(shí)現(xiàn)示例

    本文主要介紹了Qt MQTT開發(fā)環(huán)境搭建的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 使用代碼驗(yàn)證linux子進(jìn)程與父進(jìn)程的關(guān)系

    使用代碼驗(yàn)證linux子進(jìn)程與父進(jìn)程的關(guān)系

    Linux下父進(jìn)程可以使用fork 函數(shù)創(chuàng)建子進(jìn)程,但是當(dāng)父進(jìn)程先退出后,子進(jìn)程會(huì)不會(huì)也退出呢?通過下面這個(gè)小實(shí)驗(yàn),我們能夠很好的看出來
    2014-02-02
  • Qt中connect()函數(shù)及用法詳解

    Qt中connect()函數(shù)及用法詳解

    connect() 函數(shù)就是Qt 框架中用于將信號(hào)(SIGNAL)和槽(SLOT)關(guān)聯(lián)起來的核心函數(shù),本文給大家介紹Qt中connect()函數(shù),感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • 深入ORACLE變量的定義與使用的詳解

    深入ORACLE變量的定義與使用的詳解

    本篇文章是對(duì)ORACLE變量的定義與使用進(jìn)行了詳細(xì)的分析與介紹,需要的朋友參考下
    2013-05-05
  • C語言經(jīng)典順序表真題演練講解

    C語言經(jīng)典順序表真題演練講解

    程序中經(jīng)常需要將一組數(shù)據(jù)元素作為整體管理和使用,需要?jiǎng)?chuàng)建這種元素組,用變量記錄它們,傳進(jìn)傳出函數(shù)等。一組數(shù)據(jù)中包含的元素個(gè)數(shù)可能發(fā)生變化,順序表則是將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示
    2022-04-04
  • Qt定時(shí)器類QTimer使用詳解與注意事項(xiàng)

    Qt定時(shí)器類QTimer使用詳解與注意事項(xiàng)

    Qt提供了兩種定時(shí)器,一種是QObject類的定時(shí)器,另一種是QTimer類的定時(shí)器,這篇文章主要給大家介紹了關(guān)于Qt定時(shí)器類QTimer使用與注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • C/C++ 中memset() 函數(shù)詳解及其作用介紹

    C/C++ 中memset() 函數(shù)詳解及其作用介紹

    這篇文章主要介紹了C/C++ 中memset() 函數(shù)詳解及其作用介紹,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • QT的QWebEngineView類知識(shí)點(diǎn)詳細(xì)介紹

    QT的QWebEngineView類知識(shí)點(diǎn)詳細(xì)介紹

    QWebEngineView是Qt框架中的組件,基于Chromium內(nèi)核,支持HTML5、CSS3、JavaScript等Web技術(shù),適用于嵌入網(wǎng)頁內(nèi)容到Qt應(yīng)用程序,它提供了豐富的接口如加載、導(dǎo)航、與JavaScript交互等,并支持信號(hào)槽機(jī)制處理各種網(wǎng)頁事件,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字)

    C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++ 中dynamic_cast&lt;&gt;的使用方法小結(jié)

    C++ 中dynamic_cast&lt;&gt;的使用方法小結(jié)

    將一個(gè)基類對(duì)象指針(或引用)cast到繼承類指針,dynamic_cast會(huì)根據(jù)基類指針是否真正指向繼承類指針來做相應(yīng)處理
    2013-03-03

最新評(píng)論

双柏县| 闽清县| 区。| 瑞金市| 大田县| 嘉祥县| 阜阳市| 牡丹江市| 敖汉旗| 临安市| 施秉县| 钦州市| 神农架林区| 蓬安县| 文安县| 嘉定区| 丽水市| 四子王旗| 伊宁市| 若羌县| 耒阳市| 兰西县| 泽普县| 高淳县| 曲周县| 灵宝市| 南涧| 绥滨县| 定西市| 犍为县| 西乌珠穆沁旗| 常宁市| 建宁县| 建平县| 岫岩| 保德县| 安阳市| 永登县| 依兰县| 惠安县| 五莲县|