decltype类型说明符

decltype 类型说明符给定一个指定表达式的类型。与 auto 关键字一起 decltype 类型说明符,主要,编写模板库的开发人员很有用。使用 auto ,并声明返回类型的模板函数的 decltype 取决于其模板参数的类型。或者,使用 auto 和 decltype 声明包装调用另一个模板函数,然后返回该包装函数的返回类型。

 decltype( expression )

参数

Parameter

说明

expression

一个表达式。有关更多信息,请参见 表达式(C++)

返回值

expression 参数的类型。

备注

decltype 类型说明符在 Visual C++ 2010 或更高版本支持,并且可用于与本机或托管代码。

编译器使用下列规则确定 expression 参数的类型。

  • 如果 expression 参数是标识符或 类成员访问, decltype(expression) 是 expression名为的该实体的类型。如果不存在这样的实体或 expression 参数名一组重载函数,编译器会产生错误消息。

  • 如果 expression 参数是函数调用或一个重载运算符函数, decltype(expression) 是函数的返回类型。在重载运算符两边的括号被忽略。

  • 如果 expression 参数是 rvalue, decltype(expression) 是 expression的类型。如果 expression 参数是 左值, decltype(expression) 是 左值引用 到 expression的类型。

下面的代码示例演示如何 decltype 类型说明符的部分用途。首先,假定,则代码以下语句。

int var;
const int&& fx(); 
struct A { double x; }
const A* a = new A();

接下来,请检查由四个 decltype 语句在下表中返回的类型。

语句

类型

注释

decltype(fx());

const int&&

为 const int的 rvalue 引用

decltype(var);

int

变量类型 var

decltype(a->x);

double

成员访问的类型。

decltype((a->x));

const double&

内部括号引起语句会计算为表达式而不是成员访问。并且,由于 a 声明为 const 指针,该类型是对 const double。

Decltype 和自动

与 auto 关键字一起使用 decltype 类型说明符,声明,返回类型取决于其模板参数的类型的模板函数。例如,请考虑模板函数的返回类型由模板参数的类型下面的代码示例。在代码示例中, 未知 占位符指示返回类型不能指定。

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(参数opt)constoptvolatileopt−>decltype(表达式)throwopt{function_body};

在下面的代码示例中,后指定返回 myFunc 模板函数的类型取决于 tu 模板参数的类型。作为最佳的代码的做法,代码示例还使用 rvalue 引用和 forward 函数模板,支持 完全转发。有关更多信息,请参见 Rvalue引用声明:&&

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

hello, world!

42

要求

Visual C++ 2010 或更高版本。

请参见

参考

简单类型名称