引子
这篇文章主要是branding auto
这个关键字。和Item 2不同的是,本文主要是夸赞auto
的优点,而Item 2则是简单的介绍。当然auto
也有自己的问题,我们会在Item 2和Item 6中谈及它的问题。
正文
1.帮助检查初始化以及减少代码复杂度
这条很容易理解意思,不细说。直接看例子
int x1; // potentially uninitialized
auto x2; // error! initializer required
auto x3 = 0; // fine, x3's value is well-defined
2.auto
关键字比std::function
更高效
我们知道auto
和std::function
都可以用来定义函数指针,例如
auto f1 = [](const std::unique_ptr<int>& p1,const std::unique_ptr<int>& p2) {
return *p1 < *p2;
};
std::function<bool(const std::unique_ptr<int>&,std::unique_ptr<int>&)> f2 = [](
const std::unique_ptr<int>& p1,const std::unique_ptr<int>& p2) {
return *p1 < *p2;
};
但是这样定义出来的f1
是闭包类型,而f2
则是std::function
模板类,需要申请内存来保存这个闭包。这样不论是存储还是运行f2
的效率都会比较低。
甚至在C++14中,lambda表达式的参数也可以用auto
关键字了,所以我们可以更简单地写为:
auto f3 = [](const auto& p1,const auto& p2) {
return *p1 < *p2;
};
这样更简洁高效。
3.避免因为不准确的类型导致不必要的开销,甚至bug
我们再考虑下面一段代码:
std::unordered_map<std::string, int> m;
...
for (const std::pair<std::string, int>& p : m)
{
... // do something with p
}
大部分人如果不熟悉容器std::unordered_map
是很难看出这段代码的问题的。但实际上std::unordered_map
中的key一定是const
。即我们实际从std::unordered_map
中存储和返回的都是std::pair<const std::string, int>
,这和我们声明的p
类型并不一样。这就会导致循环在每次赋值给p
的时候,都会生成一个临时变量,然后在循环末尾再删除它。这样效率十分低下,甚至会无法允许你修改std::unordered_map
内部真正的值!
总结
最后我们总结如下:
1.
auto
关键字可以帮助我们检查初始化,不会因为类型不匹配或者隐式转换导致的效率问题以及可移植问题,此外还可以帮我们减少冗余代码。
2.auto
类型的变量受制于Item 2和Item 6中提到的陷阱。