《Effective Modern C++》读书笔记(4) -- 尽量使用auto来显式类型声明
来源:互联网 发布:mysql 查看表 编辑:程序博客网 时间:2024/05/21 07:59
写了三篇,发现还是有点啰嗦了,所以下面的笔记改的更为简洁些,更多的是记载自己对这本书的理解和运用。
这节包括的内容有:
- auto
- std::function
前言
在C或者C++这类语言中,声明变量的使用通常需要类型声明。例如:
int a = 10; // 声明一个整形变量a,其值为10
然而有时候我们通常只声明,不定义。例如:
int a; // 声明一个整形变量a
但是通常这样,有一个小小的问题。如果我忘了对a进行初始化,那么a的值将是未定义的。它可能为被初始化0,具体的还得依赖编译器。这也就是这一节要将的问题。
auto声明
前面写的auto类型推导中讲到过,auto声明的变量必须定义,例如下面这种用法就是不允许的。
int a; // ok!auto b; // error!auto c = 10; // ok!
对于c变量,它被推断为一个整形变量。当然从上面的例子看不出auto的强大之处。我们重新举个栗子,假如我们要声明一个函数,它的作用是进行大小的比较,代码如下:
auto derefUPLess = [](const std::unique_ptr<Widget>& p1, const std::unique_ptr<Widget>& p2){ return *p1 < *p2; };
调用很简单,例如:
derefUPLess(p1, p2)
现在我们来推导下,如果不用auto,那么derefUPLess的类型是什么,首先根据闭包,我们知道这是一个函数,且该函数带有两个参数,参数类型都是
const std::unique_ptr<Widget>&
又根据return语句知道,返回类型是bool,综上,我们知道derefUPLess的类型是
// std::function的用法在下面std::function<bool(const std::unique_ptr<Widget>&, const std::unique_ptr<Widget>&)>
使用auto极大地省略了代码量。甚至在C++14中还可以使用
// C++14auto derefUPLess = [](const auto& p1, const auto& p2){ return *p1 < *p2; };
std::function的用法
std::function是C++11添加的新特性。它是一个模板函数,用来初始化为一个函数指针。与普通的函数指针不同,函数指针只能指向一个函数,而std::function对象能引用任何可调用的对象。
使用也很简单:
std::function<Type(parameter)> func;
例如上面的代码:
std::function<bool(const std::unique_ptr<Widget>&, const std::unique_ptr<Widget>&)> derefUPLess;
使用auto而不使用std::function的理由(也是auto和std::function的不同之处)
- auto和std::function对于闭包的内存需求不一样,std::function使用的更多
- auto比std::function更快
其他注意事项
- 在32位Windows操作系统,unsigned是32位的,在64位Windows操作系统,unsigned是64位的。这时候,auto能确保你不犯错。
例如:
std::vector<int> v;... auto sz = v.size(); // std::vector<int>::size_type is unsigned. sz's type is std::vector<int>::size_type
代码
#include <iostream>#include <functional>#include <memory>class Widget{public: explicit Widget(int value) : value_(value) { // empty } bool operator<(const Widget& t) { return value_ < t.value_; }private: int value_;};int main(int argc, char const *argv[]){ std::unique_ptr<Widget> p1(std::make_unique<Widget>(1)); std::unique_ptr<Widget> p2(std::make_unique<Widget>(2)); auto derefUPLess = [](const std::unique_ptr<Widget>& p1, const std::unique_ptr<Widget>& p2) { return *p1 < *p2; }; if (derefUPLess(p1, p2)) { std::cout << "Yes" << std::endl; } else { std::cout << "No" << std::endl; } return 0;}
补充
function类似一个容器,可以容纳任意有operator()的类型(函数指针,函数对象,lambda表达式),它是运行时的,可以任意拷贝,赋值,存储其他可调用物。而auto仅是在编译期推导出的一个静态类型变量,它很难再赋以其他值,也无法容纳其他的类型,不能用于泛型编程。
当需要存储一个可调用物用于回调的时候,最好使用function,它具有更多的灵活性,特别是把回调作为类的一个成员的时候我们只能使用function。
auto也有它的优点,它的类型是在编译期推到出来的,没有运行时的开销,效率上要比function略高一点。但它声明的变量不能存储其他类型的可调用物,不具有灵活性,只能用于有限范围的延后回调。
- 《Effective Modern C++》读书笔记(4) -- 尽量使用auto来显式类型声明
- 《Effective Modern C++》读书笔记(2) -- auto类型推导(auto type deduction)
- Effective Modern C++ 条款5 尽量用auto代替显式类型声明
- 《Effective Modern C++》读书笔记(5) -- 尽量使用nullptr而不使用0和NULL
- Effective Modern C++: Item 5 -> 优先选择auto而不是显式类型声明
- [effective modern c++][5]与其使用显示类型推断不如使用auto
- 《Effective Modern C++》读书笔记
- [effective modern c++][2]理解auto类型推断
- Effective Modern C++:Item 2 ->弄清auto类型推断
- 《Effective Modern C++》读书笔记(1) -- 模板类型推导(template type deduction)
- 《Effective Modern C++》翻译--条款2: 理解auto自动类型推导
- Modern C++(一)auto自动类型推导
- Effective Modern C++: Item 4 -> 知道如何查看推断类型
- [More Effective C++]尽量使用C++风格的类型转换
- <<Effective C++>>读书笔记4: 设计与声明
- Effective Modern C++ Item2 理解auto类型推导
- Effective Modern C++ 条款2 理解auto类型推断
- Effective Modern C++ 条款6 当auto会推断出不合理的类型时使用显式类型初始化语法
- HTML5中代码调试,快捷键F10和F11区别
- jquery如何让页面的滚动条返回到顶部
- hdu 1754 I hate it (线段树,树状数组)
- 数组(Array)详解;
- 欢迎使用CSDN-markdown编辑器
- 《Effective Modern C++》读书笔记(4) -- 尽量使用auto来显式类型声明
- bat文件直接启用模拟器
- android 图片制作
- 深入浅出数据库结构(一)
- 正则表达式的概念
- 组合模式
- ObjectMapper 的一个坑
- Java项目经验——程序员成长的钥匙
- java基本数据类型