EMCPP条款5:优先选用auto而非显式型别声明
避免冗长的型别声明
lambda
表达式的返回类型可以用 auto
1 | auto derefUPLess = [](const std::unique_ptr<int>& lhs, |
在C++14中,labmda
表达式的参数列表中的参数也可以用 auto
1 | auto derefUPLess = [](auto& lhs, auto& rhs) { |
std::function
是C++11标准库中的一个模板,它把函数指针的思想加以扩展,使得它可以表示任何可调用的东西,包括函数、函数对象、lambda表达式、成员函数、成员函数指针、函数指针等等。对上述函数使用 std::function
声明:
1 | std::function<bool(const std::unique_ptr<int>&, |
- 从结果上看,
std::function
对象一般都会比使用auto
声明的变最使用更多内存。 - 从可读性上看,
std::function
对象的声明比使用auto
声明的变量要长得多。 - 从性能上看,
std::function
对象的声明比使用auto
声明的变量要慢得多。
避免“型别捷径”的问题
比如,在32位Windows上,unsigned
和 std::vector<int>::size_type
的尺寸是一样的,但在64位Windows上,unsigned
的尺寸是4字节,而 std::vector<int>::size_type
的尺寸是8字节。使用 auto
就不会有这样问题。
1 | std::vector<int> v; |
避免错误的隐式转换
比如:
1 | std::unordered_map<std::string, int> m; |
std::unordered_map
的键值是 const
,所以 std::pair
的键值应该也是 const
,即 std::pair<const std::string, int>
。编译器会努力将 std::pair<const std::string, int>
转换成 std::pair<std::string, int>
,这一步是可以成功的,但多了一次复制操作,所以最好还是使用 auto
,即:
1 | for (const auto& p : m) { |
要点速记
auto
变量必须初始化,基本上对会导致兼容性和效率问题的型别不匹配现象免疫,还可以简化重构流程,通常也比显式指定型别要少打一些字。auto
型别的变量都有着条款2和条款6中所描述的毛病。