C 0x右值 move forward 引用退化

2021-06-05 09:58:59 字數 1393 閱讀 1618

昨天又學習了下右值、move和forward。記錄一下學習到的東西:

1、引用退化

左值引用有傳染性。左值引用的右值引用或右值引用的左值引用結果都是左值引用,即:

string& &&和string&& &都等於string&

string & & 等於string &

string && &&等於string &&

2、左值和右值是表示式的屬性

即存在這個情況:某個變數的型別是右值引用,但變數自己構成的表示式卻是左值

3、具名的左值引用和右值引用都是左值,不具名的右值引用是右值

因為有名字的變數,不管是左值還是右值,在你沒有明確宣告的情況下,預設不會立即銷毀,因此不能當右值看待

4、move

不管左值引用還是右值引用,通過move後都換成右值引用

5、forward

std::forward(x)

如果t是string,那麼返回string&&;如果t是string&,那麼返回string&。返回型別和x型別無關

那為什麼叫完美**呢?和x是左值引用還是右值引用都沒有關係!!

關鍵在於這個t不是固定的,而是由編譯器從函式引數上型別推導出來的。

template t&& func(t&& x)

當用string&呼叫func時,t的型別推導為string&。由於引用退化,t&&等效於string&,因此返回值也是左值string&。

當用string&&呼叫func時,t的型別推導為string。因此返回值就是string&&。

從而做到了完美**。

因此foward的完美**一定要和模板引數自動推導關聯起來使用,單獨forward自己是沒法完美**的。

6、使用右值作為函式引數對傳統函式進行優化

一般對形如:func(const x& data)的函式進行過載優化:

func(x&& data)

當實參是x&、const x&、const x&&時,呼叫老的函式。而當實參是x&&時,呼叫新的函式以獲得效能上的提公升。

7、預設型別轉換

type&& 可以預設轉為type&、const type&、const type&&。因為它的約束是最強的。它的約束包含:

a) 指向乙個合法的物件

b) 可以修改

c) 該物件馬上將銷毀,可以偷竅其資料

而type&只包含a)、b)兩個約束 

const type&&可以預設轉為const type&

type&只能預設轉換為const type&。如需把它轉成type&&,可以使用std::move

const type&不能轉換成其它三個型別

8、const type&&沒啥存在的意義

馬上都要銷毀了,還不讓人修改,圖啥呢?

《C 0x漫談》系列

05年開始關注c 0x,其時c 0x的大部分草案其實都已經初具雛形。但幾個重大的特性 concepts,rvalue,memory model,variadic templates等都還在激烈的動盪當中。於是一路看著這些特性不斷成長,不斷出revisions。其間也跟標準委員會中的一些大牛們,如pe...

《C 0x漫談》系列

05年開始關注c 0x,其時c 0x的大部分草案其實都已經初具雛形。但幾個重大的特性 concepts,rvalue,memory model,variadic templates等都還在激烈的動盪當中。於是一路看著這些特性不斷成長,不斷出revisions。其間也跟標準委員會中的一些大牛們,如pe...

C 0x導讀 2 13 常數

返回目錄 c 0x支援以下7種型別的常數 其中後兩種是c 0x新增的 整型常數 字元常數 浮點常數 字串常數 布林常數 指標常數 自定義常數 1 整型常數 注 因為long long是c 0x才正式加入的,所以目前不同的編譯器對它的支援和標準的描述還有些出入 有三類整型常數 十進位制,以1 9開頭 ...