Decltype型別指示符

2021-09-06 15:50:20 字數 2427 閱讀 8062

有時候遇到這種情況:希望從表示式的型別推斷出要定義的變數的型別,但是不想用該表示式的值初始化變數。為了滿足這一要求,c++11新標準引入了第二種型別說明符decltype,它的作用是選擇並返回運算元的資料型別。在此過程中,編譯器分析表示式並得到它的型別,卻不實際計算表示式的值:

decltype(f()) sum=x;     //sum 的型別就是函式f的返回型別

編譯器並不實際呼叫函式f,而是使用當呼叫發生時f的返回值型別作為sum的型別。換句話說,編譯器為sum指定的型別是什麼呢?就是假如f被呼叫的話將會返回的那個型別。

decltype處理頂層const和引用的方式與auto有些不同。如果decltype使用的表示式是乙個變數,則decltype返回該變數的型別(包括頂層const和引用在內):

const int ci=0,&cj=ci; 

decltype(ci) x=0; //x的型別是const int

decltype(cj) y=x; //y的型別是const int& ,y繫結到變數x

decltype(cj) z; //錯誤,z是乙個引用const int&,必須初始化

因此cj是乙個引用,decltype(cj)的結果就是引用型別,因此作為引用的z必須被初始化。

需要指出的是,引用從來都是作為其所指物件的同義詞出現,只有用在decltype處是乙個例外。

如果decltype使用的表示式不是乙個變數,則decltype返回表示式結果對應的型別。有些表示式將向decltype返回乙個引用型別。一般來說當這種情況發生時,意味著該表示式的結果物件能作為一條賦值語句的左值:

//decltype的結果可以是引用型別

int i=42,*p=&i,&r=i;

decltype(r+0) b; //

正確:加法的結果是int,因此b是乙個(未初始化的)int

decltype(*p) c; //

錯誤,c是int&,必須初始化

因為r是乙個引用,因此decltype(r)的結果是引用型別。如果想讓結果是r所指的型別,可以把r作為表示式的一部分,如r+0,顯然這個表示式的結果將是乙個具體值而非乙個引用。

另一方面,如果表示式的內容是解引用操作,則decltype將得到引用型別。正如我們所熟悉的那樣,解引用指標可以得到指標所指的物件,而且還能給這個物件賦值。因此,decltype(*p)的結果型別就是int&,而非int。

decltype和auto的另乙個重要的區別是,decltype的結果型別與表示式密切相關。有一種情況需要特別注意:對於decltype所用的表示式來說,如果變數加上了一對括號,則得到的型別與不加括號時會有很大的不同。如果decltype使用的是乙個不加括號的變數,則得到的結果就是該變數的型別;如果給變數加上一層或多層括號,編譯器就會把它當成是乙個表示式。變數是一種可以作為賦值語句左值的特殊表示式,所以這樣的decltype就會得到引用型別:

//

decltype的表示式如果是加上括號的變數,結果將是引用

decltype((i)) d;

//錯誤:d是int&,必須初始化

decltype(i) e; //

正確:e是乙個(未初始化的)int

切記:decltype((variable))(注意是雙括號)的結果永遠是引用,而decltype(variable)結果只有當variable本身是乙個引用時才是引用。

c++的表示式要不然是左值,要不然就是右值。這兩個名詞是從c語言繼承過來的,原本是為了幫助記憶;左值可以位於賦值語句的左側,右值則不能。

在c++中,二者的區別沒有那麼簡單。乙個左值表示式的求值結果是乙個對或者函式,然而以常量物件為代表的某些左值實際上不能作為賦值語句的左側運算子物件。此外,雖然某些表示式的求值結果是物件,但它們是右值而非左值。可以做乙個簡單的歸納:當乙個物件被用作右值的時候,用的是物件的值(內容);當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)。

不同的運算子對運算物件的要求各不相同,有的需要 左值運算物件、有的需要右值運算物件;返回值也有差異,有的得到左值結果,有的得到右值結果。一種重要的原則是在需要右值的地方可以用左值來代替(std::move)但是不能把右值當成左值(也就是位置)使用。當乙個左值被當成右值使用時,實際使用的是它的內容(值)。到目前為止,已經有幾種我們熟悉的運算子是要用到左值的。

接下來在介紹運算子的時候,我們將會註明該運算子的運算物件是否必須是左值以及其求值結果是否是左值。

使用關鍵字decltype的時候,左值和右值也有所不同。如果表示式的求值結果是左值,decltype作用於該表示式(不是變數)得到乙個引用型別。舉個例子,假定p的型別是int* ,因為解引用運算子生成左值,所以decltype(*p)的結果是int&。另一方面,因為解位址運算子生成右值,所以decltype(&p)的結果是int**,也就是說,結果是乙個指向整型指標的指標。

C 之decltype型別指示符

decltype 的功能 得到表示式的返回值型別,用於對新變數的宣告或定義。有如下幾點需要注意 1 作用於常量型別得到的還是常量型別。2 作用於引用型別得到的還是引用型別,此時需要對變數初始化。3 當引用作為表示式的一部分,作用於該表示式得到的將不是引用型別。4 decltype variable ...

C 11decltype型別指示符

c 11引入型別說明符decltype,作用是選擇並返回運算元的資料型別,在此過程中,編譯器分析表示式並得到它的型別,卻不計算表示式的值 decltype f sum x sum的型別就是函式f返回的型別編譯器並不實際呼叫函式f,而是返回f呼叫發生時的返回型別作為sum的型別。decltype處理c...

C decltype型別指示符

有些情況下,我們希望從表示式的型別推斷出要定義的變數的型別,但是不想用該表示式的值初始化變數。此時就要用到c 11引入的第二種型別說明符delctype,它的作用就是選擇並返回運算元的資料型別。編譯器分析表示式並得到它的型別,但不實際計算表示式的值 decltype size 5 s i declt...