1.自动类型推断
1.1.auto
a.auto声明变量的类型必须由编译器在编译时期推导而得。
int main(){double foo();auto x = 1;//x类型为intauto y = foo();// y类型为doubleauto z;// errreturn 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;//intconst auto ii = 1;//const intauto& ci = 1;//const int&volatile int p = 1;auto pp = p;// intvolatile ppp = p;//volatile intconst 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为intauto 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* constint 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;
}