C++ decltype類型解釋符。本站提示廣大學習愛好者:(C++ decltype類型解釋符)文章只能為提供參考,不一定能成為您想要的結果。以下是C++ decltype類型解釋符正文
1 根本語法
decltype 類型解釋符生成指定表達式的類型。在此進程中,編譯器剖析表達式並獲得它的類型,卻不現實盤算表達式的值。
語法為:
decltype( expression )
編譯器應用以下規矩來肯定expression 參數的類型。
假如 expression 參數是標識符或類成員拜訪,則 decltype(expression) 是 expression 定名的實體的類型。假如不存在此類實體或 expression 參數定名一組重載函數,則編譯器將生成毛病新聞。
假如 expression 參數是對一個函數或一個重載運算符函數的挪用,則 decltype(expression) 是函數的前往類型。將疏忽重載運算符雙方的括號。
假如 expression 參數是右值,則 decltype(expression) 是 expression類型。假如 expression參數是左值,則 decltype(expression) 是對 左值援用 類型的expression。
給出以下示例代碼:
int var; const int&& fx(); struct A { double x; } const A* a = new A();
語句 類型 正文
decltype(fx()); const int && 對左值援用的const int
decltype(var); int 變量 var 的類型
decltype(a->x); double 成員拜訪的類型
decltype((a->x)); const double& 外部括號招致語句作為表達式而不是成員拜訪盤算。因為a聲明為 const指針,是以類型是對const double的援用。
2 decltype和援用
假如decltype應用的表達式不是一個變量,則decltype前往表達式成果對應的類型。然則有些時刻,一些表達式向decltype前往一個援用類型。普通來講,當這類情況產生時,意味著該表達式的成果對象能作為一條賦值語句的左值:
// decltype的成果可所以援用類型 int i = 42, *p = &i, &r = i; decltype(r + 0) b; // OK, 加法的成果是int,是以b是一個(未初始化)的int decltype(*p) c; // Error, c是int&, 必需初始化
由於r是一個援用,是以decltype(r)的成果是援用類型,假如想讓成果類型是r所指的類型,可以把r作為表達式的一部門,如r+0,明顯這個表達式的成果將是一個詳細的值而非一個援用。
另外一方面,假如表達式的內容是解援用操作,則decltype將獲得援用類型。正如我們所熟習的那樣,解援用指針可以獲得指針所指對象,並且還能給這個對象賦值,是以,decltype(*p)的成果類型是int&而非int。
3 decltype和auto
處置頂層const和援用的方法分歧(參考浏覽:C++ 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; // Error, z是一個援用,必需初始化
decltype的成果類型與表達式情勢親密相干
關於decltype所用的援用來講,假如變量名加上了一對括號,則獲得的類型與不加括號時會有所分歧。假如decltype應用的是一個不加括號的變量,則獲得的成果就是該變量的類型;假如給變量加上了一層或多層括號,編譯器就會把它當做是一個表達式。
decltype((i)) d; // Error, d是int&, 必需初始化 decltype(i) e; // OK, e是一個未初始化的int
模板函數的前往類型
在 C++11 中,可以聯合應用尾隨前往類型上的 decltype 類型解釋符和 auto 症結字來聲明其前往類型依附於其模板參數類型的模板函數。
在 C++14 中,可使用不帶尾隨前往類型的 decltype(auto) 來聲明其前往類型取決於其模板參數類型的模板函數。
例如,界說一個乞降模板函數:
//C++11 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); }; //C++14 template<typename T, typename U> decltype(auto) myFunc(T&& t, U&& u) { return forward<T>(t) + forward<U>(u); };
(forward:假如參數是右值或右值援用,則有前提地將其參數強迫轉換為右值援用。)
附上一段源碼:
#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; }
運轉成果為:
Plus(i, 9) = 13 Plus(dx, dy) = 13.5 Hello, world! x3.Dump() = 42