C++11 decltype

有下面這個情況:

template <class T1, class T2>
void ft (T1 &x, T2 &y)
{
	...
	?type? xpy = x+;
	...	
}

在這種情況下xpy應該是什麼類型呢?由於不知道ft()將如何使用,因此無法預知這一點。正確的類型可能是T1、T2或者其他類型。假如又出現了重載運算符,這會讓問題更加的複雜。

於是爲了解決這個問題,c++11新增了關鍵字 decltype。

我們可以這樣使用:

int x;
decltype(x) y;//y的類型和x類型一致

除了上述這樣寫,我們也可以這樣寫:

decltype(x+y) xpy;
xpy = x+y;

通過這個關鍵字,我們可以把前面的代碼修改成這樣:

template <class T1, class T2>
void ft(T1 x, T2 y)
{
	...
	decltype(x+y) xpy = x+y;

	...
}

decltype比這些實例要複雜些。爲了確定類型,編譯器必須遍歷一個覈對表。假設有如下聲明:

decltype (expression) var;

1.如果expression是一個沒有用括號括起的標識符,則var的類型與該標識符類型相同,包括const等限定符

double x = 5.5;
double y = 7.9
double &rx = x;
const double *pd;
decltype(x) w; // w is type double 
decltype (rx) u = y; // u is type double &
decltype(pd) v; // v is type const double *

2.如果expression是一個函數調用,則var的類型與函數的返回類型相同:

long indeed(int)
decltype (indeed(3)) m; // is type int

這裏並不會實際調用函數。編譯器通過查看函數的原型來獲悉返回類型,而無需實際調用函數。

3.加入expression是用括號括起來的標識符:

double xx = 4.4;
decltype((xx)) r2 = xx ; // r2 is double &
decltype(xx) w = xx; // w is double

括號並不會改變表達式的值和左值性。

4.如果前面都不滿足,則var的類型與expression類型相同:

int j = 3;
int &k  = j;
int  &n = j;
decltype (j+6)i1; // i1 type int
decltype (100L) i2; // i2 type long
decltype (k+n) i3; // i3 type int

雖然k和n都是引用,是表達式k+n不是引用。

如果需要多次聲明,可以結合使用typdef和decltype:

template <class T1, class T2>
void ft(T1 x, T2 y)
{
	typedef decltype (x+y) xytype;
	xytype xpy = x+y;
	xytype arr[10];
	xytype &rxy = arr[2]; // rxy a reference
}

還有一個問題是decltype沒有辦法解決的:

template <class T1, class T2>
?type? gt(T1 x, T2 y)
{
	return x+y;	
}

同樣無法預知x和y相加得到的類型。看起來我們還可以用decltype,但是很不幸,這個時候還沒有聲明x和y,它們不在作用域內。必須在聲明參數後使用decltype。爲此,c++新增了一種聲明和定義函數的語法。

double h(intx, float y);

可以用新增的語法編寫成這個樣子:

auto h(int x, float y) -> double;

這將返回類型移到了參數聲明後面。->double被稱爲後置返回類型(trailing return type)。 其中auto是一個佔位符,表示後置返回類型提供的類型。這是c++11的新增auto語法。這個語法也可以用於函數定義。

auto h (int x, float y) -> double
{/* function body*/};

通過結合使用這種語法和decltype,便可以給gt()指定返回類型。

template <class T1, class T2>
auto gt(T1x, T2 y)  ->decltype(x+y)
{
	return x+y;
}

現在,decltype在參數聲明後面,因此x和y位於作用域內,可以使用它們。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章