auto和decltype都是类型推断的方式,但又有一定的区别:
1.编译器的作用
- auto类型说明符 通过 编译器计算变量的初始值 来推断其类型
- 而decltype是让编译器分析其表达式推断其类型,并不是计算表达式的值。
2.编译器推断出来的auto类型与初始值类型可能有出入,编译器会适当地改变其结果使auto更符合初始化规则。
- auto会忽略顶层const而把底层留下来。
#include<iostream>
#include<string>
using namespace std;
int main()
{
const string str01 = "asdad";
for (auto a :str01)//a为char类型
{
a = '1';//成功赋值
}
return 0;
}
- 而decltype会保留变量的顶层const。
#include<iostream>
#include<string>
using namespace std;
int main()
{
const string str01 = "asdad";
for (decltype(str01) a :str01)//a为const char 类型,本迭代无法进行
{
a = '1';//const无法赋值
}
return 0;
}
3.与auto不同,decltype的结果类型与表达式的形式密切相关
-
如果变量名不加括号,结果就是该变量的类型
-
如果加上了一层或多层括号,则编译器会推断得到引用类型。
一个实例:
#include<iostream>
#include<typeinfo>
int main()
{
int a = 3;
auto c1 = a;
decltype(a) c2 = a;
decltype((a)) c3 = a;
const int d = 5;
auto f1 = d;
decltype(d)f2 = d;
std::cout << typeid(c1).name() << std::endl;
std::cout << typeid(c2).name() << std::endl;
std::cout << typeid(c3).name() << std::endl;
std::cout << typeid(f1).name() << std::endl;
std::cout << typeid(f2).name() << std::endl;
c1++;
c2++;
c3++;
f1++;
f2++;
std::cout << a << " "
<< c1 << " "
<< c2 << " "
<< c3 << " "
<< f1 << " "
<< f2 << std::endl;
return 0;
}
VS2019自动提示:
因为decltype(d)f2 = d;保留了const int d的顶层,所以f2为const int型,无法自加;
而auto f1 = d;忽略了const int d的顶层,所以f1为 int型,可以自加;
注释掉f2++;后的运行结果如下:
int
int
int
int
int
4 4 4 4 6 5