decltype关键字
跟auto一样,也是用来实现类型推导,但是auto只能根据变量的初始化表达式来推导,即必须初始化。
decltype也是在编译时推导,不会实际计算表达式的值,类似于一元运算符sizeof
推导规则:
1、如果对decltype使用的表达式是一个不加括号的变量,或者是一个类成员变量访问表达式,则推导出的类型为表达式一致,且保留CV限定与引用
如:
2、如果对decltype使用的表达式是函数调用,推导出的类型和返回值一致,如果函数返回的是一个临时变量,推导类型为右值引用,如果函数是重载函数,编译器将报错
如:
3、如果对decltype使用的表达式结果是左值,推导出的类型为左值引用,表达式结果是右值,则推导出的类型为右值的类型
如:
4、如果对decltype使用的表达式被括号括起来了,类型推导的结果永远是左值引用
如:
5、C++ primer上的一个情况
解释:因为r是一个引用,因此decltype (r)的结果为引用类型,如果想让结果类型时r所指的类型,可以把r作为表达式的一部分,如r + 0,显然这个表达式的结果将是一个具体的值而非一个引用
应用
1.推导出表达式类型
2.与using/typedef合用,用于定义类型。
3.重用匿名类型
4.泛型编程中结合auto,用于追踪函数的返回值类型
参考:
C++11特性:decltype关键字 http://www.cnblogs.com/QG-whz/p/4952980.html
C++ Primer
深入应用C++ 11
跟auto一样,也是用来实现类型推导,但是auto只能根据变量的初始化表达式来推导,即必须初始化。
decltype也是在编译时推导,不会实际计算表达式的值,类似于一元运算符sizeof
如:
decltype (func()) sum = x; //sum的类型为函数func的返回值的类型,这里并不调用函数func
推导规则:
1、如果对decltype使用的表达式是一个不加括号的变量,或者是一个类成员变量访问表达式,则推导出的类型为表达式一致,且保留CV限定与引用
如:
volatile const int& x = 0;
decltype (x) a ; //a -> const volatile int& 同时,由于没有对引用进行初始化,此句错误
int *p = &x;
decltype (p)* pp = &p; //pp -> int **
class Foo
{
public:
static const int NUmber = 0;
int x;
}
decltype (Foo::NUmber) c = 0; //c -> const int
Foo foo;
decltype (foo.x) d = 0; //d -> int
int h = 0;
decltype (h) i = 0; //i -> int
2、如果对decltype使用的表达式是函数调用,推导出的类型和返回值一致,如果函数返回的是一个临时变量,推导类型为右值引用,如果函数是重载函数,编译器将报错
如:
decltype (Foo()) j = 0; //j -> Foo&& 构造函数返回了临时变量
int&& fun();
decltype (fun()) K = 0; //k -> int&&
int func();
decltype (func()) sum = x; //sum -> int 普通函数调用
const int func_cint ();
decltype (func_cint()) l = 0; //l -> int 函数返回值为右值
const Foo func_cfoo();
decltype (func_cfoo()) m = Foo; //m -> const Foo 返回值为类类型的右值可以带CV限定符
3、如果对decltype使用的表达式结果是左值,推导出的类型为左值引用,表达式结果是右值,则推导出的类型为右值的类型
如:
//此段代码摘自:http://www.cnblogs.com/QG-whz/p/4952980.html
int i = 4;
int arr[5] = { 0 };
int *ptr = arr;
decltype (true ? i : i) var7 = i; //int& 条件表达式返回左值。
decltype (++i) var8 = i; //int& ++i返回i的左值。
decltype (arr[5]) var9 = i;//int&. []操作返回左值
decltype (*ptr)var10 = i;//int& *操作返回左值
decltype ("hello")var11 = "hello"; //const char(&)[9] 字符串字面常量为左值,且为const左值。
decltype (1) var12;//const int
decltype (i++) var14 = i;//int i++返回右值
int n = 0, p = 0;
decltype (n + p) q; //q ->int
decltype (n += p) r; //r ->int&
4、如果对decltype使用的表达式被括号括起来了,类型推导的结果永远是左值引用
如:
int y = 0;
decltype ((y)) z; //z -> int& 同时,由于没有对引用进行初始化,此句错误
5、C++ primer上的一个情况
int i = 42, &r = i;
decltype (r + 0) b; //b -> int
解释:因为r是一个引用,因此decltype (r)的结果为引用类型,如果想让结果类型时r所指的类型,可以把r作为表达式的一部分,如r + 0,显然这个表达式的结果将是一个具体的值而非一个引用
应用
1.推导出表达式类型
2.与using/typedef合用,用于定义类型。
3.重用匿名类型
4.泛型编程中结合auto,用于追踪函数的返回值类型
参考:
C++11特性:decltype关键字 http://www.cnblogs.com/QG-whz/p/4952980.html
C++ Primer
深入应用C++ 11