1. decltype的意義
有時我們希望從表達式的類型推斷出要定義的變量類型,但是不想用該表達式的值初始化變量(初始化可以用auto
)。為了滿足這一需求,C++11新標准引入了decltype
類型說明符,它的作用是選擇並返回操作數的數據類型,在此過程中,編譯器分析表達式並得到它的類型,卻不實際計算表達式的值。
2. decltype用法
-
(1) 基本用法
int getSize(); int main(void) { int tempA = 2; /*1.dclTempA為int.*/ decltype(tempA) dclTempA; /*2.dclTempB為int,對於getSize根本沒有定義,但是程序依舊正常,因為decltype只做分析,並不調用getSize().*/ decltype(getSize()) dclTempB; return 0; }
-
(2) 與const結合
double tempA = 3.0; const double ctempA = 5.0; const double ctempB = 6.0; const double *const cptrTempA = &ctempA; /*1.dclTempA推斷為const double(保留頂層const,此處與auto不同)*/ decltype(ctempA) dclTempA = 4.1; /*2.dclTempA為const double,不能對其賦值,編譯不過*/ dclTempA = 5; /*3.dclTempB推斷為const double * const*/ decltype(cptrTempA) dclTempB = &ctempA; /*4.輸出為4(32位計算機)和5*/ cout<<sizeof(dclTempB)<<" "<<*dclTempB<<endl; /*5.保留頂層const,不能修改指針指向的對象,編譯不過*/ dclTempB = &ctempB; /*6.保留底層const,不能修改指針指向的對象的值,編譯不過*/ *dclTempB = 7.0;
-
(3) 與引用結合
int tempA = 0, &refTempA = tempA; /*1.dclTempA為引用,綁定到tempA*/ decltype(refTempA) dclTempA = tempA; /*2.dclTempB為引用,必須綁定到變量,編譯不過*/ decltype(refTempA) dclTempB = 0; /*3.dclTempC為引用,必須初始化,編譯不過*/ decltype(refTempA) dclTempC; /*4.雙層括號表示引用,dclTempD為引用,綁定到tempA*/ decltype((tempA)) dclTempD = tempA; const int ctempA = 1, &crefTempA = ctempA; /*5.dclTempE為常量引用,可以綁定到普通變量tempA*/ decltype(crefTempA) dclTempE = tempA; /*6.dclTempF為常量引用,可以綁定到常量ctempA*/ decltype(crefTempA) dclTempF = ctempA; /*7.dclTempG為常量引用,綁定到一個臨時變量*/ decltype(crefTempA) dclTempG = 0; /*8.dclTempH為常量引用,必須初始化,編譯不過*/ decltype(crefTempA) dclTempH; /*9.雙層括號表示引用,dclTempI為常量引用,可以綁定到普通變量tempA*/ decltype((ctempA)) dclTempI = ctempA;
-
(4) 與指針結合
int tempA = 2; int *ptrTempA = &tempA; /*1.常規使用dclTempA為一個int *的指針*/ decltype(ptrTempA) dclTempA; /*2.需要特別注意,表達式內容為解引用操作,dclTempB為一個引用,引用必須初始化,故編譯不過*/ decltype(*ptrTempA) dclTempB;
3. decltype總結
decltype和auto都可以用來推斷類型,但是二者有幾處明顯的差異:
-
auto忽略頂層const,decltype保留頂層const;
-
對引用操作,auto推斷出原有類型,decltype推斷出引用;
-
對解引用操作,auto推斷出原有類型,decltype推斷出引用;
-
auto推斷時會實際執行,decltype不會執行,只做分析。總之在使用中過程中和const、引用和指針結合時需要特別小心。