1 auto类型推导
1.1 auto类型推导的意义
auto x = 5;
auto pi = new auto(1); //pi被推导成int* new int(1);
const auto *v = &x, u=6; //v是const int*类型, u是const int类型
static auto y = 0.0; //y是double类型
auto int r; //错误,auto不再表示存储类型指示符
auto s; //auto无法推导出s的类型
v和u的推导要注意两点:
-
虽然经过前面const auto *v = &x的推导,auto的类型可以确定为int了,但是u仍然必须要写后面的“=6”,否则编译器不予通过。
-
u的初始化不能是编译器推导产生二义性。例如,把u的初始化改为“u=6.0”,编译器将会报错。
auto并不能代表一个实际的类型声明(如s的编译错误),只是一个类声明类型的“占位符”。使用auto声明的变量必须马上初始化,以让编译器推断出它的实际类型,并在编译时将auto替换为真正的类型。
隐式类型定义的类型推导发生在编译期,它的作用是让编译器自动推断出这个变量的类型,而不需要显示指定类型。
1.2 auto的推导规则
- 当不声明为指针或引用时,auto的推导结果和初始化表达式抛弃引用和cv限定符后类型一致。
- 当声明为指针或引用时,auto的推导结果将保持初始化表达式的cv属性。
int x = 0;
auto *a = &x; //a -> int*,auto被推导为int
auto b = &x; //b -> int*,auto被推导为int*
auto &c = x; //c -> int&,auto被推导为int
auto d = c; //d -> int ,auto被推导为int,表达式是引用,抛弃掉引用属性
const auto e = x; //e -> const int,auto被推导为int,const auto在编译期间会被替换成const int
auto f = e; //f -> int,抛弃掉了const属性
const auto& g = x; //g -> const int&,auto和引用(或指针)一起使用时,const属性将被保留
auto &h = g; //h -> const int&
1.3 auto的限制
- 不能用于函数参数;
- 不能用于非静态成员变量;
- auto无法定义数组;
- 无法推导出模板参数。
在类中,auto仅能用于推导static const的整型或者枚举成员(因为其他静态类型在C++标准中无法就地初始化),C++可以接受非静态成员变量的初始化,却不支持auto类型非静态成员变量的初始化。
1.4 auto的使用场景
- 定义了一个stl容器,在遍历的时候
- 在无法知道变量被定义成什么类型的时候
2 decltype
2.1 获知表达式的类型
int x = 0;
decltype(x) y = 1; //y -> int
decltype(x+y) z = 0; //z -> int
const int& i = x;
decltype(i) j = y; //j -> const int&
const decltype(z)*p = &z; //*p -> const int, p -> const int*
decltype(z) *pi = &z; //*pi
decltype(pi) *pp = π
3.auto和decltype的结合使用----返回类型后置语法
为了解决函数返回值类型依赖于参数而导致难以确定返回值类型的问题。
template<typename T, typename U>
auto add(T t, U u) -> decltype(t+u)
{
return t+u;
}