5. 优先使用auto而非显示类型声明
在C++之中,使用auto关键字声明类型可以将程序员从输入繁琐的类型中解放出来,编译器会自动推导出变量的实际类型。
template<typename It>
void dwim(It b, It e)
{
while(b != e){
typename std::iterator_traits<It>::value_type
currValue = *b;
...
}
}
使用auto关键字
template<typename It>
void dwim(It b, It e)
{
while(b != e){
auto currValue = *b;
...
}
}
在C++14中,lambda函数的参数都可以使用auto来定义。
auto derefLess = // C++14 comparison
[](const auto& p1, // function for
const auto& p2) // values pointed
{ return *p1 < *p2; };
使用auto生命类型还可以将我们从类型截断的问题中解放出来:
std::vector<int> arrs;
auto size = arrs.size();
在C++中,unordered_map
的key的类型是const类型的,所以即便采取如下方式遍历unordered_map
容器,仍然会产生临时对象:
std::unordered_map<std::string, int> m;
...
for (const std::pair<std::string, int>& p : m)
{
... // do something with p
}
但是借助auto,我们不仅使声明更加简洁,还避开了此问题:
std::unordered_map<std::string, int> m;
...
for (const auto& p : m)
{
... // do something with p
}
6. 当auto推导出非预期类型时应当使用显示的类型初始化
在C++中,因为标准不允许返回对bit的引用,所以对于vector<bool>
标准库进行了特化处理,其[]
运算符返回的是std::vector<bool>::reference
类型的临时对象。对临时对象的修改会被其同步到vector中,因而这样使用auto关键字是不合规的。
Widget w;
…
auto highPriority = features(w)[5]; // w是不是个高优先级的?
…
processWidget(w, highPriority); // 配合优先级处理w
在这种情况下,我们只需显示指出highPriority
的类型为bool即可规避此问题。