auto
在编译期间,自动根据后面的类型进行类型推导
迭代器
- 正常情况下:
std::vector<std::string> container;
for(std::vector<std::string>::iterator i= container.begin(); i!=container.end(); i++)
{
}
- 使用auto的情况
std::vector<std::string> container;
for(auto i= container.begin(); i!=container.end(); i++)
{
}
可以auto 可以大大降低代码的复杂度
模板
在定义模板参数的时候,申明的变量依赖于模板参数的时候:
template <typename _Tx, typename _Ty>
void My_Fun(_Tx x, _Ty y)
{
auto result = x*y;
cout << result;
}
或者返回值依赖于模板参数:
auto My_Fun(_Tx x, _Ty y)->decltype(x*y)
{
return x*y;
}
decltype 是 C++11标准引入的新的运算符,用于查询表达式的数据类型。auto在这里称作返回值占位,真正的返回值在后面decltype(xy),那为什么不把decltype(xy)放前面,decltype(x*y)My_Print(_Tx x, _Ty y), xy还没定义,肯定报错啊。
for 循环
// 1. 遍历数组
int data[10] = {1,2,3,4,5,6,7,8,9,10};
for(auto i:data)
{
cout << i << " ";
}
// 2. 遍历容器
vector<int> container;
for(int i=0; i<10; i++)
{
container.push_back(i);
}
for(auto data:container)
{
cout << data << " ";
}
// 3.遍历字符串
string str = "julian";
for(auto c:str)
{
cout << c << " ";
}
// 4.遍历map容器
map<string, string> container = {{"1", "julian"},{"2","kerr"},{"3","jack"}};
for(auto i:container)
{
cout << i.first << " : " << i.second << endl;
}
注意事项
- 定义auto序列变量的时候,必须推导类型都是一样的
auto a=10, b=5, c=10; //正确
auto a=10, b=5, c=10.0; // 错误
- 函数或者模板的参数不能申明为auto
template <auto T> // 错误
void My_Fun(auto para) //错误,好像C++14允许了
{
}
- 如果变量为const或者volatile,auto 则去掉const/volatile的语义,可以理解auto 只是推导类型,并不包括const/volatile,但是auto& 则不去除。
const int a = 100;
auto b = a; // b 是int
b = 10; // OK
const auto c = a; // c 是 const int
c = 10; // 错误
// 但是使用 auto& 则不去除const volatile的语义
auto& d = a; // d 是 const int
d = 10; // 错误,如果d 不是const ,可以改变a的值,显然不合理
- 变量是引用,auto 则没有引用的语义,auto& 保留引用
int a = 10;
int& b = a;
auto& c = b; // c int&
auto d = b ; // d int
c = 1; // a 改变
d = 1; // a 不改变
- 使用数组初始化
int data[10] ={0};
auto var1 = data; // var1是 int*
auto& var2 = data; // var2是 int[10]
cout << sizeof(var2) << endl; // 40
cout << sizeof(var1) << endl; // 8
对于以上的几种规则,可以直接记忆auto 只是无脑的代替类型,auto&保留原来的特性
decltype
它和auto有相似的作用,但是它和auto有区别:
常见用法
int a =10;
decltype(a)& b = a; // delatype(a)=int , b是a 的引用, int&
b = 101; // a 也被改变了
与const在一起使用
int const a =10;
decltype(a) b = a; // b: const int 型
b = 101; // 错误
和引用在一起使用
int a =10;
int& b = a;
decltype(b) c = a; // c : int&
c = 101; // a 被改变
decltype((a)) c = a; // 双层括号代表引用
c = 101 ;// a 被改变
和指针在一起使用
int a =10;
int* b = &a;
decltype(b) c; // c是 int*
decltype(*b) d = a; // d 是int& 必须初始化
总结:decltype和auto 都可以进行类型推导,但是有区别:
- 对于const , auto 去掉,decltype保留
- 对于引用,auto去掉,decltype保留
- auto 在推断的时候做执行,decltype只分析,不执行
typeid
得到变量的类型:typeid(var).name()