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 模板函数的类型取决于 t 和 u 模板参数的类型。作为最佳的代码的做法,代码示例还使用 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 或更高版本。