当前位置: 代码迷 >> 综合 >> Effective Modern C++ 笔记二: auto
  详细解决方案

Effective Modern C++ 笔记二: auto

热度:93   发布时间:2024-01-30 21:07:08.0

条款5:优先选用auto,而非显式型别声明

简化声明

auto defefLess = [](const auto& p1, const auto& p2) {return *p1 < *p2; };

引入:

std::function

这个是函数指针的一种推广,可以指涉任何可调用对象。若要创建一个std::function对象就必须指定欲指涉的函数的型别。

例如:

bool(const std::unique_ptr<widget>&, const std::unique_ptr<widget>&)//对应std::function<bool(const std::unique_ptr<widget>&, const std::unique_ptr<widget>&)> func;//因为lambda表示式产生可调用对象,std::function对象中就可以存储闭包。 所以在c++11中,不用
//auto也可以声明上面的derefUPLess
std::function<bool(const std::unique_ptr<widget>&, const std::unique_ptr<widget>&)>

注意:

std::function对象一般都会比使用auto声明的变量使用更多内存。通过std::function来调用闭包几乎必然会比通过使用auto声明的变量来调用同一闭包来的慢。

除了避免未初始化变量和啰嗦的变量声明,并且可以直接持有闭包外,还可以避免一类称为“型别捷径”的问题。

例如:

std::unordered_map<std::string, int> m;for(const std::pair<std::string, int>& p : m)
{//...
}

因为std::unordered_map的键值部分是const,所以编译器会试图将std::pair<const std::string, int>对象转换为std::pair<std::string, int> 对象。

结果会对m中的每个对象做一次复制操作,形成一个p想要绑定的型别的临时对象,然后将p这个引用绑定到该临时对象上,迭代结束后会析构该临时对象,使用auto可以避免这种隐晦的问题。


条款6:当auto推导的型别不符合要求时,使用带显式型别的初始化物习惯用法

例如:

Widget w;bool highPriority = features(w)[5];processWidget(w, highPriority)/////////////////////////////////auto highPriority = features(w)[5];processWidget(w, highPriority);

因为std::vector<bool>::operator[]特化为std::vector<bool>::reference对象,所以会出问题(highPriority含有一个垂悬指针)。

 

通常的,避免写出 auto somevar = "隐形"代理型别表达式。

但是可以这样:

auto highPriority = static_cast<bool>(features(w)[5]);

所以

1:一些不明显的代理类有可能使得你的auto推断与设想中的不一致。

2:显式初始化转化可以使得auto推导出想要的型别。

 

 

 

 

 

  相关解决方案