auto关键字
C++11 引入了 auto 和 decltype 关键字实现类型推导,通过这两个关键字不仅能方便地获取复杂的类型,而且还能简化书写,提高编码效率
auto的使用规则
auto x = 5; // OK: x是int类型
auto pi = new auto(1); // OK: pi被推导为int*
const auto *v = &x, u = 6; // OK: v是const int*类型,u是const int类型
static auto y = 0.0; // OK: y是double类型
auto int r; // error: auto不再表示存储类型指示符
auto s; // error: auto无法推导出s的类型
int x = 0;
auto * a = &x; // a -> int*,auto被推导为int
auto b = &x; // b -> int*,auto被推导为int*
auto & c = x; // c -> int&,auto被推导为int
auto d = c; // d -> int ,auto被推导为int
const auto e = x; // e -> const int
auto f = e; // f -> int
const auto& g = x; // e -> const int&
auto& h = g; // f -> const int&
💡 auto可以推断出一般的数据类型以及数据类型的指针
auto的限制
void func(auto a = 1) {} // error: auto不能用于函数参数
struct Foo
{
auto var1_ = 0; // error: auto不能用于非静态成员变量
static const auto var2_ = 0; // OK: var2_ -> static const int
};
template <typename T>
struct Bar {};
int main(void)
{
int arr[10] = {0};
auto aa = arr; // OK: aa -> int *
auto rr[10] = arr; // error: auto无法定义数组
Bar<int> bar;
Bar<auto> bb = bar; // error: auto无法推导出模板参数
return 0;
}
- auto不能用于函数参数
- auto不能用于非静态成员变量
- auto无法定义数组
- auto无法推导出模板参数
auto的使用
1、STL容器
#include <map>
int main(void)
{
std::map<double, double> resultMap;
// ...
std::map<double,double>::iterator it = resultMap.begin();
for(; it != resultMap.end(); ++it)
{
// do something
}
return 0;
}
使用auto后
#include <map>
int main(void)
{
std::map<double, double> resultMap;
// ...
for(auto it = resultMap.begin(); it != resultMap.end(); ++it)
{
// do something
}
return 0;
}
#include <map>
int main(void)
{
std::unordered_multimap<int, int> resultMap;
// ...
std::pair< std::unordered_multimap<int,int>::iterator, std::unordered_multimap<int, int>::iterator > range = resultMap.equal_range(key);
return 0;
}
使用auto后
#include <map>
int main(void)
{
std::unordered_multimap<int, int> map;
// ...
auto range = map.equal_range(key);
return 0;
}
2、简化函数定义
class Foo
{
public:
static int get(void)
{
return 0;
}
};
class Bar
{
public:
static const char* get(void)
{
return "0";
}
};
template <class A>
void func(void)
{
auto val = A::get();
// ...
}
int main(void)
{
func<Foo>();
func<Bar>();
return 0;
}
在这个例子里,我们希望定义一个泛型函数 func,对所有具有静态 get 方法的类型 A,在得到 get 的结果后做统一的后续处理。若不使用 auto,就不得不对 func 再增加一个模板参数,并在外部调用时手动指定 get 的返回值类型