C++ 类型推导:auto和decltype
类型推导:auto和decltype
auto
基本用法
使用它来做自动类型推导,可以和其他操作符(&,*,const),一般来说auto 是根据变量的初始值来推导出变量类型的,比如一些容器的迭代器完整写下来就很长,使用auto就很方便
1 | |
auto trick
=右边是一个引用类型时auto会自动把引用抛弃,推导出原始类型:这是符合直觉的,我们希望引用与否掌握在程序员手上,因此这种帮助了我们根据意志自由决定。
1 | |
- 当类型不为引用时,
auto的推导结果将不保留表达式的const属性; - 当类型为引用时,
auto的推导结果将保留表达式的const属性。
对于上边两条做出解释:
1.当类型不为引用时,auto 的推导结果将不保留表达式的 const属性;
1 | |
2.当类型为引用时,auto 的推导结果将保留表达式的 const 属性。
1 | |
这么做的原因是为了安全,如果你的auto推出的是int,那么也就是说可以通过这个引用去修改一个const的变量,这是不合理的(编译器会禁止这样做)。因此为了合理性、安全性,推导出const int是最好的选择。
- auto 不能在函数的参数中使用 (版本低于C++20)
如果为了减少代码重复,模板是一个更好的替代方法
注意:C++20已经允许auto在函数参数中使用了
1 | |
- auto 不能作用于类的非静态成员变量(也就是没有 static 关键字修饰的成员变量)中
1 | |
- auto 关键字不能定义数组 (char[]不行,用char*的可以)
1 | |
Reference : https://stackoverflow.com/questions/7107606/why-cant-i-create-an-array-of-automatic-variables
虽然auto x[4] ={ ....}是一个错误的用法,但是auto x = {1,2,3,4}会推出x是一个std::initializer_list<int>类型。
- auto 不能作用于模板参数
1 | |
decltype
基本用法
decltype和auto不同,他使用exp表达式进行类型推导 (decltype(10.8) x = 5.5 ; x被推导成了 double)
值得一提的是,decltype并不会计算表达式,因此不用担心decltype(fun())或decltype(a+b+c+d+e+f...) 执行函数、表达式造成的耗费空间/时间。
decltype + 变量
当使用decltype(var)的形式时,decltype会直接返回变量的类型,包括const 和 &,这是一种完美的保留。
1 | |
decltype和数组组合时:结果是一个数组
1 | |
decltype和指针组合
1 | |
decltype+表达式
当使用decltype(expr)的形式时,decltype会返回表达式结果对应的类型。一个表达式不是左值就是右值,因此,decltype(expr)的结果根据expr的结果不同而不同: expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。
1 | |
当一个变量作为表达式时,即decltype((var))会推断出左值引用“
decltype单独作用于对象,没有使用对象的表达式的属性,而是直接获得了变量的类型。要想获得变量作为表达式的类型,可以加一个括号:decltype((var))
1 | |
decltype+函数:
decltype作用于函数名会得到函数类型,注意这里是函数名,不是函数调用,函数调用返回的是一个变量,因此属于上面decltype+变量的部分。
C++中通过函数的返回值和形参列表,定义了一种名为函数类型的东西。它的作用主要是为了定义函数指针
比如:
1 | |
我们可以从过decltype获得fun的类型:
1 | |
学会查看推导结果
第一种方法就是通过IDE来查看
第二种通过编译器报错来查看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15using FunType = int(const int&,int);
int fun(const int& x,int y)
{
cout<<x<<" "<<y<<endl;
return x+y;
};
template<typename T>
class TD;
int main()
{
TD<decltype(fun)>xtype;
return 0;
}报错:
error: aggregate 'TD<int(const int&, int)> xtype' has incomplete type and cannot be defined|,可以得知:fun是int(const int&, int)类型。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!