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

一文搞懂C++11萬能引用和右值引用

 更新時(shí)間:2022年03月25日 10:43:03   作者:luoyayun361  
本文主要介紹了C++11萬能引用和右值引用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

我們通過一個問題來進(jìn)入今天的話題:
1.形如 “type&&” 的結(jié)構(gòu),就是右值引用嗎?
2.以下哪些屬于右值引用?

① void fun(Widget && param);
② Widget && var1= Widget();
③ auto && var2 = var1;
④ template<typename T> void f(std::vector<T>&& param);
⑤ template<typename T> void f(T&& param);

帶著以上的問題,我們來看一下到底type&&的結(jié)構(gòu)包含了哪些含義。

正文

實(shí)際上,type&& 有兩種不同的含義。
其中一種就是 右值引用。它僅僅會綁定右值,用于識別出可移對象。
另外一種含義,則表示既可以是右值引用,也可以是左值引用。這種雙重特性使其可以綁定到右值,也可以綁定到左值。還可以綁定到const對象或非const對象,以及volatile對象,甚至可以綁定那些既帶有const又帶有volatile的對象,擁有很強(qiáng)的靈活性,這就是萬能引用。

那么,既然以上兩種含義都是 type&& 結(jié)構(gòu),那么如何來區(qū)分二者呢?

萬能引用

萬能引用通常會在兩種場景現(xiàn)身:函數(shù)模板的形參 和 auto聲明。
示例如下:

template<typename T> 
void f(T&& param);   //param是個萬能引用
 auto && var2 = var1;

以上兩種場景的共同之處,在于它們都涉及型別推導(dǎo)。

在模板f中,param的類型是推導(dǎo)得到的,而在var2的聲明語句中,var2的類型也是推導(dǎo)得到的。

因?yàn)槿f能引用首先是個引用,所以初始化是必須的。萬能引用的初始化物會決定它代表的是個左值還是右值引用,如果初始化物是左值,萬能引用就會對應(yīng)得到一個左值引用,同理,如果初始化物是右值,萬能引用就會對應(yīng)得到一個右值引用。
對于作為函數(shù)形參的萬能引用而言,初始化物在調(diào)用處提供:

template<typename T>?
void f(T&& param);

Widget w;
f(w); ? ?? ??? ? ?//左值被傳遞給f,param的類型是Widget&,即左值引用

f(std::move(w)); ?//右值被傳遞給f,param的類型是Widget&&,即右值引用

有一個需要注意的問題是,萬能引用除了要涉及型別推導(dǎo),還有一個條件必須限定,就是必須要是“T&&”結(jié)構(gòu)才行。
而類似

template<typename T> 
void f(std::vector<T>&& param);   //param是右值引用

這樣的類型并不是萬能引用,僅僅只是一個右值引用。

而且,如果有const修飾也不可能成為萬能引用,比如:

template<typename T> 
void f(const T&& param);  //param是右值引用

那么,位于模板內(nèi)是不是就一定就會涉及到型別推導(dǎo)呢? 還真不能保證??匆韵率纠?/p>

template <class T,class Allocator = allocator<T>>
class vector{
public:
    void push_back(T&& x);
    ...
};

以上是來自C++標(biāo)準(zhǔn)中vector類

這里的push_back的形參具備萬能引用的正確形式,但是在本示例中,并不涉及到類型推導(dǎo)。因?yàn)閜ush_back作為vector本身的一部分,如果不存在特定的vector實(shí)例,則它也無從存在。該實(shí)例的具體類型完全決定了push_back的聲明類型。
如:

std::vector<Widget> v;

會導(dǎo)致std::vector模板具現(xiàn)化為如下實(shí)例:

template <class Widget,class Allocator = allocator<Widget>>
class vector{
public:
    void push_back(Widget&& x);  //右值引用
    ...
};

現(xiàn)在就能看清楚push_back并未涉及到類型推導(dǎo)。

而vector中的另外一個函數(shù)卻涉及到了類型推導(dǎo),如下:

template <class T,class Allocator = allocator<T>>
class vector{
public:
    template<class... Args>
    void emplace_back(Args&&... args);
    ...
};

以上emplace_back函數(shù)的形參 Args獨(dú)立于vector的型別形參T,所以Args必須在每次emplace_back被調(diào)用時(shí)進(jìn)行推導(dǎo)。所以這里的args是個萬能引用。

最后,我們前面也提到過,auto變量也可以作為萬能引用。確切的說,聲明為auto&&的變量都是萬能引用,因?yàn)榭隙ㄉ婕暗叫蛣e推導(dǎo)并且肯定有正確的形式(“T&&”)

比如在C++14中 lambda表達(dá)式可以聲明auto&&形參。

結(jié)語

通過以上描述,終于搞清楚了萬能引用和右值引用的區(qū)別,那么回到文中最前面的問題,③⑤都是萬能引用,其他三個為右值引用,這下不會搞錯了。

總結(jié)如下:

  • 如果函數(shù)模板形參具備T&&型別,并且T的型別是推導(dǎo)而來,或如果對象使用auto&&聲明其類型,則該形參或?qū)ο缶褪侨f能引用
  • 如果型別聲明不精確地具備type&&的形式,或者型別推導(dǎo)并未發(fā)生,則type&&就代表右值引用
  • 若采用右值來初始化萬能引用,就會得到一個右值引用,如果采用左值來初始化,則會得到一個左值引用。

參考:

Effective Modern C++

到此這篇關(guān)于一文搞懂C++11萬能引用和右值引用的文章就介紹到這了,更多相關(guān)C++11萬能引用和右值引用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于C語言中的指針與二維數(shù)組

    關(guān)于C語言中的指針與二維數(shù)組

    這篇文章主要介紹了關(guān)于C語言中的指針與二維數(shù)組,C語言中,指針是一個復(fù)雜但又靈活多變的知識點(diǎn),我們知道,在一維數(shù)組中,對于一個數(shù)組a[],*a,a,&a,都表示a的首地址,但如果與二維數(shù)組混合使用,就顯得更為復(fù)雜了,需要的朋友可以參考下
    2023-07-07
  • 淺談C++中的構(gòu)造函數(shù)分類及調(diào)用規(guī)則

    淺談C++中的構(gòu)造函數(shù)分類及調(diào)用規(guī)則

    這篇文章主要介紹了C++中的構(gòu)造函數(shù)分類及調(diào)用規(guī)則,文中根據(jù)參數(shù)寫出了幾種不同類型的構(gòu)造函數(shù)并解釋了如何調(diào)用,需要的朋友可以參考下
    2016-03-03
  • 簡要說明C語言中指針函數(shù)與函數(shù)指針的區(qū)別

    簡要說明C語言中指針函數(shù)與函數(shù)指針的區(qū)別

    這篇文章主要介紹了C語言中指針函數(shù)與函數(shù)指針的區(qū)別,指針函數(shù)和函數(shù)指針是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-04-04
  • C語言中strcpy()函數(shù)的具體實(shí)現(xiàn)及注意事項(xiàng)

    C語言中strcpy()函數(shù)的具體實(shí)現(xiàn)及注意事項(xiàng)

    C語言庫函數(shù)char *strcpy(char *dest, const char *src)把src所指向的字符串復(fù)制到dest,下面這篇文章主要給大家介紹了關(guān)于C語言中strcpy()函數(shù)的具體實(shí)現(xiàn)及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • C++動態(tài)規(guī)劃之背包問題解決方法

    C++動態(tài)規(guī)劃之背包問題解決方法

    這篇文章主要介紹了C++動態(tài)規(guī)劃之背包問題解決方法,實(shí)例分析了背包問題的原理與C++實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • VisualStudio 使用Visual Leak Detector檢查內(nèi)存泄漏

    VisualStudio 使用Visual Leak Detector檢查內(nèi)存泄漏

    這篇文章主要介紹了VisualStudio 使用Visual Leak Detector檢查內(nèi)存泄漏的相關(guān)資料,需要的朋友可以參考下
    2015-07-07
  • C++ STL中vector容器的使用

    C++ STL中vector容器的使用

    這篇文章主要為大家詳細(xì)介紹了C++ vector容器的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • VC++的if語句應(yīng)用范圍分析

    VC++的if語句應(yīng)用范圍分析

    這篇文章主要介紹了VC++的if語句應(yīng)用范圍分析,對VC++初學(xué)者有很好的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2014-08-08
  • C++使用WideCharToMultiByte函數(shù)生成UTF-8編碼文件的方法

    C++使用WideCharToMultiByte函數(shù)生成UTF-8編碼文件的方法

    用來映射Unicode字符串的WideCharToMultiByte函數(shù)經(jīng)常被用來進(jìn)行UTF-8編碼的轉(zhuǎn)換,以下我們將看到C++使用WideCharToMultiByte函數(shù)生成UTF-8編碼文件的方法,首先先來對WideCharToMultiByte作一個詳細(xì)的了解:
    2016-06-06
  • C++數(shù)組放在main函數(shù)內(nèi)外的區(qū)別

    C++數(shù)組放在main函數(shù)內(nèi)外的區(qū)別

    大家好,本篇文章主要講的是C++數(shù)組放在main函數(shù)內(nèi)外的區(qū)別,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01

最新評論

宜州市| 襄汾县| 板桥市| 溧水县| 额尔古纳市| 东乌珠穆沁旗| 玛纳斯县| 讷河市| 台山市| 梁平县| 同心县| 门头沟区| 凤台县| 微山县| 阳高县| 梅河口市| 沅江市| 虎林市| 元江| 开原市| 静安区| 银川市| 上饶市| 光山县| 商丘市| 建始县| 汝阳县| 铁岭市| 衡东县| 东海县| 九龙县| 新营市| 融水| 榕江县| 合肥市| 南开区| 云霄县| 历史| 永仁县| 石嘴山市| 嘉荫县|