编译器支持最低版本要求:
- GCC: 4.3(v1.0), 4.8.1(v1.1)
- MSVC: 16.0(v1.1)
- Clang: 2.9
大概是为了更好地配合auto进行自动类型推导,C++11引入了decltype操作符,用于检查某个实体(比如变量)的声明类型或表达式的类型及值分类,所以有以下用法:
decltype(entity)
decltype(expression)
括号是必不可少的,但也是需要慎重使用的,因为表达式如果被括号括着,会被当做通常的左值表达式,所以decltype(x)和decltype((x))通常会得到不同的结果:
int i;
decltype(i) a; // a: int
decltype((i)) b; // b: int &,无法编译通过
一般说来,C++11按以下规则来返回decltype(x)的类型:
- 如果
x是一个没有带括号的标记符表达式(id-expression)或者类成员访问表达式,那么decltype(x)就是x所命名的实体的类型。如果x是一个被重载的函数,则会导致编译错误。 - 否则,假设
x的类型是T,如果x是一个将亡值(xvalue),那么decltype(x)结果为T&&。 - 否则,假设
x的类型是T,如果x是一个左值(lvalue),那么decltype(x)结果为T&。 - 否则,假设
x的类型是T,x是一个纯右值(prvalue),那么decltype(x)结果为T。
左值、右值(将亡值、纯右值)
C++11之前,程序内的值分为左值(lvalue)和右值(rvalue)两种:
- 可以取地址的,有名字的就是左值
- 不能取地址的,没有名字的就是右值
比如a = b + c中,a就是左值,b + c就是右值,粗略地可以通过看它是在赋值表达式中赋值符的左边还是右边。
C++11中,右值(rvalue)又细分为将亡值(xvalue,eXpiring value)和纯右值(prvalue,pure rvalue):
- 纯右值就是C++11之前标准中的右值
- 将亡值是C++11新增的跟右值引用相关的表达式,比如返回右值引用
T&&的函数返回值,std::move的返回值,转换为T&&的类型转换函数的返回值
推导函数返回值类型
配合auto和decltype,可以自动推导函数返回值类型:
template<class T, class U>
auto add(T t, U u) -> decltype(t + u) // the return type is the type of operator+(T, U)
{
return t + u;
}