auto类型推到的原理_深挖右值与左值
1.
如果初始化表达式是引用,首先去除引用,如果 auto 类型关键字带上 & 则不进行去除;
以下程序程序示例中可以看到 myAuto 是一个 int,而不是引用 int。
#include <iostream>
using namespace std;
int main( )
{
int count = 10;
int& countRef = count;
auto myAuto = countRef;
countRef = 11;
cout << count << " ";
myAuto = 12;
cout << count << endl;
}
// 11
// 11
2.
auto 关键字的类型完美转发:
C++11 使用 auto 声明变量时,如:auto&& var=initValue;,则此时 “auto&&” 并不意味着这一定是右值引用类型的变量,而是类似于模板函数参数的类型推导,既可能是左值引用,也可能是右值引用。其目的是把初始化表达式的值分类情况,完美转发给由 auto 声明的变量。也即:
1)如果初始化值是类型 A 的左值,则声明的变量类型为左值引用 A&;
2)如果初始化值是类型 A 的右值,则声明的变量类型为右值引用 A&&。
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
struct Widget
{
}; // 类
Widget makeWidget()
{ // 函数
return Widget(); // 类工厂函数
}
int main()
{
Widget &&var1 = Widget(); // var1的类型是右值引用,但是作为左值
auto &&var2 = var1; // var2的类型是左值引用
std::vector<int> v = {1, 2, 3};
auto &&val = v[0]; // std::vector::operator[]的返回值是元素左值,所以val的类型是左值引用
Widget &&var3 = makeWidget(); // var3是左值,但它的类型是右值引用
Widget var4 = static_cast<Widget &&>(var1); // var4是左值,但它的类型是右值引用
std::cout << typeid(var1).name() << std::endl;
std::cout << typeid(var2).name() << std::endl;
std::cout << typeid(val).name() << std::endl;
std::cout << typeid(var3).name() << std::endl;
std::cout << typeid(var4).name() << std::endl;
}
// std::type_info::name()方法返回的字符串,表示参数的类型名,通常是以一个数为开头,表示类型的编码,在这个编码后面跟着是类型的名称
/*
6Widget//6是类型的编码,Widget是类型名称+
6Widget
i
6Widget
6Widget*/