程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ decltype類型解釋符

C++ decltype類型解釋符

編輯:關於C++

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved