1.自动类型推断
1.1.auto
a.auto声明变量的类型必须由编译器在编译时期推导而得。
int main(){
double foo();
auto x = 1;//x类型为int
auto y = foo();// y类型为double
auto z;// err
return 0;
}
b.auto声明得变量必须被初始化。
c.针对指针和引用
推导类型是指针类型时,可以使用auto或auto*形式。
推导类型是引用类型时,必须使用auto&形式。
int main()
{
int x;
auto p = &x;//int*
auto* p2 = &x;//int*
auto& q = x;// int&
auto qq = x;// int
}
d.针对类型修饰符const 和 volatile
采用auto&形式时,若右边表达式含义const属性,结果类型也含const属性。若没有,则不含。
采用auto形式时,结果类型不会包含const属性。但可通过const auto自行添加。
结果类型不会包含volatile属性。但可通过volatile auto自行添加。
int main()
{
auto i = 1;//int
const auto ii = 1;//const int
auto& ci = 1;//const int&
volatile int p = 1;
auto pp = p;// int
volatile ppp = p;//volatile int
const int ci = 1;
const int* const cp = &ci;
auto t = cp;//const int*。舍弃的const是修饰cp自身的。const int中的const不属于cp,会作为指针指向整体推断出来。
}
e.一次采用auto定义多个变量场景
int main()
{
int a;
auto * p = &a, q = a;// p为int*,q为int
auto qq = a, t = 1.1f;// err。qq =a中auto被推断为int。t=1.1f中auto又被推断为float。
}
e.1.采用auto,一行定义多个变量,多个变量共享auto,其余的类型修饰符各自独立。如修饰p的*对q不起作用。
e,2,采用auto,一行定义多个变量,每个变量定义时推导的auto应该类型一致。qq,t推导的auto不一致,引发了编译报错。
f.不可用场景
#include <iostream>
using namespace std;
void fun(auto x = 1){} // err。auto不可用于修饰函数形参。
struct str{
auto var = 10;// err。auto不可用于修饰类型非静态成员字段。
};
int main(){
auto z[3] = {1,2,3};//err。auto不可用于修饰数组。
std::vector<auto> v = {1};//auto不可用于作为实例化模板的模板参数。
}
1.2.decltype
#include <typeinfo>
#include <iostream>
using namespace std;
int main()
{
int i;
decltype(i) j = 0;
cout << typeid(j).name() << endl;
float a;
double b;
decltype(a+b) c;
cout << typeid(c).name() << endl;
return 0;
}
(1).decltype的类型推导基于表达式,类型是表达式的结果类型。auto基于初始化时的初始值推导类型。
(2).decltype的类型推导发生在编译时,auto也是。
(3).实例
#include <iostream>
// int
// const int
// int&
// int&&
// const int&
// const int&&
// int*
// const int*
// const int* const
int fun1() {
return 1;
}
const int fun2() {
return 1;
}
int a = 0;
const int ca = 1;
int& fun3() {
a = 1;
return a;
}
int&& fun4() {
a = 1;
return std::move(a);
}
const int& fun5(){
return 1;
}
const int&& fun6(){
return 1;
}
int* fun7(){
return &a;
}
const int* fun8(){
return &ca;
}
const int* const fun9(){
return &ca;
}
int main()
{
decltype (fun1) a1;
decltype (fun2) a2;
decltype (fun3) a3;
decltype (fun4) a4;
decltype (fun5) a5;
decltype (fun6) a6;
decltype (fun7) a7;
decltype (fun8) a8;
decltype (fun9) a9;
return 0;
}
上述a1~a9推断所得类型将严格和表达式返回类型一致,它们是int、const int、int&、int&&、const int&、const int&&、int*、const int*、const int* const。
1.3.追踪返回类型
(1). 实例
template<typename T1, typename T2>
auto Sum(T1& t1, T2& t2) -> decltype(t1+t2){
return t1+t2;
}
auto func() -> int
{
return 1;
}
上述实例利用追踪返回类型定义函数,追踪返回类型也可用于函数类型声明。
(2).可利用追踪返回类型简化复杂类型定义
#include <type_traits>
#include <iostream>
using namespace std;
int (*(*pf())())(){
return nullptr;
}
auto pf1() -> auto (*)() -> int (*)(){
return nullptr;
}
int main(){
cout << is_same<decltype(pf), decltype(pf1)>::value << endl;
return 0;
}