我们可以使用typeid运算符来查询一个变量的类型,这种类型查询在运行时进行。RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通过name成员函数返回类型的名称。同时在C++11中typeid还提供了hash_code这个成员函数,用于返回类型的唯一哈希值。RTTI会导致运行时效率降低,且在泛型编程中,我们更需要的是编译时就要确定类型,RTTI并无法满足这样的要求。编译时类型推导的出现正是为了泛型编程,在非泛型编程中,我们的类型都是确定的,根本不需要再进行推导。
一. auto 1. 推导规则- 使用auto声明的变量必须要进行初始化
auto a = 10; // 正确 auto b; // 错误
- 定义在一个auto序列的变量必须始终推导成同一类型
auto a = 10, b = 20, c = 30; // 正确 auto x = 10, y = 20.0, z = 'a'; // 错误
- 如果初始化表达式是引用,则去除引用语义
int a = 10; int& b = a; auto c = b; // int auto& d = b; // int& c = 100; // a=10 d = 100; // a=100
- 忽略顶层const,保留底层const
int a = 9; int* const pa1 = &a; // int* const (顶层const) const int* pa2 = &a; // const int* (底层const) const int* const pa3 = &a; // const int* const(底层const和顶层const) auto ppa1 = pa1; // int* auto ppa2 = pa2; // const int* auto ppa3 = pa3; // const int*
- 如果auto关键字前带上const,则补充顶层const
int i = 0, & ri = i; const int ci = 2, & rci = ci; const auto cb = i; // int -> const int const auto cb1 = ci; // const int -> int -> const int const auto ca1 = &i; // int* -> int* const const auto ccp = &ci; // const int* -> const int * const
- 如果auto关键字带上&号,则保留顶层const
const int a = 10; auto& b2 = a; // const int
- 初始化表达式为数组时
int arr1[3] = { 1, 2, 3 };
auto arr2 = arr1;
auto& arr3 = arr1;
cout << typeid(arr2).name() << endl; // int*
cout << typeid(arr3).name() << endl; // int[3]
2. 应用场景
- 用于代替冗长复杂、变量使用范围专一的变量声明
#include#include vector vecStr; for (vector ::iterator it = vecStr.begin(); it != vecStr.end(); ++it) { //... } for (auto it = vecStr.begin(); it != vecStr.end(); ++it) { //.. }
- 在定义模板函数时,用于声明依赖模板参数的变量类型
templatevoid Multiply(_Tx x, _Ty y) { auto v = x * y; cout << v; }
- 模板函数的返回值依赖于模板的参数
template二、decltypeauto multiply(_Tx x, _Ty y)->decltype(_Tx*_Ty) { return x*y; } // 如果没有后置返回类型,则函数声明为 decltype(_Tx*_Ty)multiply(_Tx x, _Ty y) // 错误,此时_Tx, _Ty还未声明,编译不通过
decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。
1. 推导规则- decltype(var),直接返回变量的类型
int i = 100, * pi = &i;
const int ci = 0, & cri = ci;
int arr[] = { 1,2,3,4,5 };
decltype(i) x; // int
decltype(ci) y = 0; // const int
decltype(cri) z = x; // const int&
decltype(pi) a; // int*
decltype(arr) b; // int[5]
- decltype(expr),返回表达式结果对应的类型。expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。
int i = 100, * p = &i, & r = i; decltype(r + 0) a; // int 算术表达式返回右值 decltype(*p) b = i; // int&
- 要想获得变量作为表达式的类型,可以加一个括号
int i = 42; decltype((i)) ri = i; // int&
- decltype(function_name),返回对应的函数类型,不会自动转换成相应的函数指针
// 函数类型 using FuncType = int(int&, int); int add(int &num1, int num2); // 函数指针 FuncType *pf = add; // 通过函数指针调用函数 int a = 4; pf(a, 2); decltype(add) *pf = add;
参考:https://www.cnblogs.com/QG-whz/p/4951177.html
参考:https://blog.csdn.net/u014609638/article/details/106987131



