昨天又學習了下右值、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開頭 ...