decltype 型別規範
decltype型別規範會產生指定之運算式的型別。decltype型別規範,以及自動關鍵字,是很有幫助主要是開發人員撰寫樣板程式庫。使用auto和decltype宣告樣板函式的傳回類型取決於它的樣板引數的型別。或者,您也可以使用auto和decltype宣告樣板函式呼叫另一個函式,會換行,則會傳回包裝函式的傳回型別。
decltype( expression )
參數
參數 |
描述 |
---|---|
expression |
這是一個運算式。如需詳細資訊,請參閱 運算式 (C++)。 |
傳回值
expression 參數的型別。
備註
decltype型別規範會支援 Visual C++ 2010年或更新的版本,並可與原生或 managed 程式碼。
編譯器會使用下列規則來決定哪種expression參數。
如果expression參數是一個識別元 (含) 類別成員存取, decltype(expression)是透過指名的實體的型別expression。如果沒有這類的實體或expression參數名稱的一組多載函式,編譯器會產生錯誤訊息。
如果expression參數是呼叫函式或函式多載的運算子, decltype(expression)是函式的傳回型別。多載的運算子前後的括號會被忽略。
If the expression parameter is an rvalue, decltype(expression) is the type of expression.If the expression parameter is an lvalue, decltype(expression) is an lvalue reference to the type of expression.
下列程式碼範例會示範幾種使用的decltype的型別規範。首先,假設您已編碼的下列陳述式。
int var;
const int&& fx();
struct A { double x; }
const A* a = new A();
接下來,請檢查型別所傳回的四個decltype下表中的陳述式。
陳述式 |
型別 |
備註 |
---|---|---|
decltype(fx()); |
const int&& |
右值參考到const int。 |
decltype(var); |
int |
變數的型別var。 |
decltype(a->x); |
double |
成員存取的型別。 |
decltype((a->x)); |
const double& |
內部的括號會導致要被評估為代替成員存取運算式的陳述式。而且因為a宣告為const指標型別是參考const double。 |
Decltype] 及 [自動
使用decltype型別規範,以及auto關鍵字來宣告樣板函式的傳回型別取決於其樣板引數的型別。比方說,請考慮下列的程式碼範例中的樣板函式的傳回型別而定的樣板引數的型別。在程式碼範例中, 未知預留位置表示不能指定傳回型別。
template<typename T, typename U>
UNKNOWNfunc(T&& t, U&& u){ return t + u; };
導入decltype型別規範可以讓開發人員以取得範本函式會傳回運算式的型別。使用替代函式宣告語法的更新版本中,顯示auto關鍵字,以及decltype的型別規範來宣告晚期指定傳回型別。宣告在編譯時,而非程式碼時,將決定晚期指定傳回型別。
下列的原型說明替代函式宣告的語法。請注意, const和volatile辨識符號,以及throw例外狀況規格是選擇性的。Function_body 預留位置代表複合陳述式,可指定函式的用途。的最佳程式設計作法,作為運算式中的版面配置區decltype陳述式應該會符合所指定的運算式return陳述式中,如果有的話,在 function_body。
autofunction_name(parametersopt)constoptvolatileopt−>decltype(expression)throwopt{function_body};
在下列程式碼範例中,最遲指定的傳回型別myFunc樣板函式由各種t和u的樣板引數。作為最佳程式設計作法,在程式碼範例也使用右值的參考和forward函式樣板支援完美轉送。如需詳細資訊,請參閱 右值參考的宣告子: & &。
template<typename T, typename U>
auto myFunc(T&& t, U&& u) -> decltype (forward<T>(t) + forward<U>(u))
{ return forward<T>(t) + forward<U>(u); };
Decltype 和轉送之函式
轉送函式來包裝其他函式呼叫。請考慮會轉送它的引數或牽涉到這些引數,另一個函式的運算式結果的函式樣板。此外,轉送函式會傳回呼叫其他函式的結果。在這種情況下,轉送函式的傳回型別應該是包裝函式的傳回型別相同。
在這個案例中,您無法寫入不適當的型別運算式decltype的型別規範。decltype型別規範可讓一般的轉送功能,因為它不會遺失所需的資訊是否函式會傳回參考的型別。轉送函式的程式碼範例,請參閱前一個myFunc樣板函式範例。
範例
下列程式碼範例會宣告晚期指定傳回型別樣板函式的Plus()。Plus函式會處理兩個運算元與operator+多載。因此,加法運算子 (+) 和傳回型別解譯Plus函式的函式引數的型別而定。
// decltype_1.cpp
// compile with: /EHsc
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <utility>
#include <iomanip>
using namespace std;
template<typename T1, typename T2>
auto Plus(T1&& t1, T2&& t2) ->
decltype(forward<T1>(t1) + forward<T2>(t2))
{
return forward<T1>(t1) + forward<T2>(t2);
}
class X
{
friend X operator+(const X& x1, const X& x2)
{
return X(x1.m_data + x2.m_data);
}
public:
X(int data) : m_data(data) {}
int Dump() const { return m_data;}
private:
int m_data;
};
int main()
{
// Integer
int i = 4;
cout <<
"Plus(i, 9) = " <<
Plus(i, 9) << endl;
// Floating point
float dx = 4.0;
float dy = 9.5;
cout <<
setprecision(3) <<
"Plus(dx, dy) = " <<
Plus(dx, dy) << endl;
// String
string hello = "Hello, ";
string world = "world!";
cout << Plus(hello, world) << endl;
// Custom type
X x1(20);
X x2(22);
X x3 = Plus(x1, x2);
cout <<
"x3.Dump() = " <<
x3.Dump() << endl;
}
Output
這個程式碼範例會產生下列結果。
13
13.5
下面顯示
42
需求
Visual C++ 2010年或較新版本。