溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++11萬(wàn)能引用和右值引用的方法

發(fā)布時(shí)間:2022-03-25 13:36:23 來(lái)源:億速云 閱讀:165 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹了C++11萬(wàn)能引用和右值引用的方法的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇C++11萬(wàn)能引用和右值引用的方法文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。

正文

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

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

萬(wàn)能引用

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

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

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

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

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

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

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

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

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

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

這樣的類型并不是萬(wàn)能引用,僅僅只是一個(gè)右值引用。

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

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

那么,位于模板內(nèi)是不是就一定就會(huì)涉及到型別推導(dǎo)呢? 還真不能保證。看以下示例:

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

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

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

std::vector<Widget> v;

會(huì)導(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中的另外一個(gè)函數(shù)卻涉及到了類型推導(dǎo),如下:

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

關(guān)于“C++11萬(wàn)能引用和右值引用的方法”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“C++11萬(wàn)能引用和右值引用的方法”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI