Effective Modern C++:06lambda表达式】的更多相关文章

/*********************************************************** 关于书: 书是我从网上找到的effective Modern C++的样章,内容只到条款4就没有了, 所以现阶段我只能翻译到条款4,不过以后有机会我会继续翻译的. 如果读者找到了完整的版本,欢迎大家发给我.1021842556@qq.com effective Modern C++的样章的下载地址http://pan.baidu.com/s/1ntKBlpf 提取密码是upk…
北京时间2016年1月9日10:31:06.正式開始翻译.水平有限,各位看官若有觉得不妥之处,请批评指正. 之前已经有人翻译了前几个条目,有些借鉴出处:http://www.cnblogs.com/magicsoar/p/3966177.html?utm_source=tuicool&utm_medium=referral 如今就開始<Effective Modern C++>翻译之旅,第一个姿势--简单介绍 Introduction 假设您是一位专家级别的C++project师,和我…
本文记录了我读Effective Modern C++时自己的一些理解和心得. item1:模板类型推导 1)reference属性不能通过传值参数传入模板函数.这就意味着如果模板函数需要一个reference类型的参数,必须在模板声明中将其声明为reference,否则,即使使用一个reference类型的变量调用模板函数,类型推导的结果将不带reference属性. 2)constant和volatile属性也不能通过传值参数传入模板函数,但是可以通过reference参数传入这些属性. 3…
写了非常多关于C++11的博客.总是认为不踏实,非常多东西都是东拼西凑.市场上也非常少有C++11的优秀书籍,但幸运的是Meyers老爷子并没有闲赋.为我们带来了<effective modern c++>. 我们都要认清,一个人非常难超越自我,超越自我的巅峰之作.由于不同的时代.也会早就不同的伟大作品. 说上面这段话的意思就是,我们不能期待<effective modern c++>能达到<effective c++>给我们带来的惊喜,可是也是出自大师之手. Lear…
lambda表达式实际上是语法糖,任何lambda表达式能做到的,手动都能做到,无非是多打几个字.但是lambda作为一种创建函数对象的手段,实在太过方便,自从有了lambda表达式,使用复杂谓词来调用STL中的”_if”族算法(std::find_if,std::remove_if等)变得非常方便,这种情况同样发生在比较函数的算法族上.在标准库之外,lambda表达式可以临时制作出回调函数.接口适配函数或是语境相关函数的特化版本以供一次性调用.下面是关于lambda相关术语的提醒: lambd…
裸指针有着诸多缺点:裸指针的声明中看不出它指向的是单个对象还是数组:裸指针的声明中也无法看出使用完它指向的对象后是否需要删除,也就是声明中看不出裸指针是否拥有其指向的对象:即使知道要析构裸指针指向的对象,也不可能知道如何析构才是恰当的:即使确知要使用delete来析构,也无法判定到底使用delete还是delete[]:使用裸指针也无法保证在程序多个代码路径上仅执行一次析构,不执行析构会造成内存泄漏,多次析构又会产生未定义行为:无法判断出裸指针是否是空悬指针. 智能指针的提出,就是用来解决裸指针…
07:在创建对象时注意区分()和{} 自C++11以来,指定初始化值的的方式包括使用小括号,等号,以及大括号: ); // initializer is in parentheses ; // initializer follows "=" }; // initializer is in braces }; // initializer uses "=" and braces C++将后两种使用大括号的两种方式视为相同的方式. C++11之前,单纯的直接初始化和复制…
C++的官方钦定版本,都是以ISO标准被接受的年份命名,分别是C++98,C++03,C++11,C++14,C++17,C++20等.C++11及其后续版本统称为Modern C++. C++11之前,仅有一套类型推导规则,也就是函数模板的推导.C++11之后,又增加了了auto和decltype的推导规则.模板推导规则是auto的基础. 首先需要介绍顶层const和底层const 的概念:指针本身是不是常量以及指针所指的对象是不是一个常量,这是两个相互独立的问题.顶层const(top-le…
http://www.cnblogs.com/kongyiyun/archive/2010/10/19/1855274.html 使用Lambda表达式将会造成Lambda表达式主题部分的代码重复. var allEmployees = new List<Employee>() { new Employee { EmployeeId = 1, Classification = 1, FirstName = "Skin", LastName = "Sen"…
条款6:当auto推导出意外的类型时,使用显式的类型初始化语义 条款5解释了使用auto来声明变量比使用精确的类型声明多了了很多的技术优势,但有的时候,当你想要zag的时候,auto可能会推导出了zig.例如,我有一个函数,它以const Widget&作为参数,并且返回std::vector<bool>,每一个bool暗示了Widget是否提供了一个特殊的特性. std::vector<bool> features(const Widget& w); 进一步假设第…
条款3 了解decltype decltype是一个有趣的东西,给它一个变量名或是一个表达式,decltype会告诉你这个变量名或是这个表达式的类型,通常,告诉你的结果和你预测的是一样的,但是偶尔的结果也会让你挠头思考,开始找一些参考资料进行研究,或是在网上寻找答案. 我们从典型的例子开始,因为它的结果都是在我们预料之中的,和模板类型推导与auto类型推导相比(参见条款1和条款2),decltype几乎总是总是返回变量名或是表达式的类型而不会进行任何的修改 ; // decltype(i)是co…
条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,auto的类型推导规则和模板的类型推导规则是一样的,但是为什么会这样呢?模板的类型推导涉及了模板,函数和参数,但是auto的类型推导却没有涉及其中的任何一个. 这确实是对的,但这无关紧要,在auto类型推导和template之间存在一个直接的映射,可以逐字逐句的将一个转化为另外一个. 在条款1中,模板类型推导是以下面的模板形式进行举例讲解的:…
条款6 当推断意外类型时使用显式的类型初始化语句 基础知识 当使用std::vector<bool>的时候,类型推断会出现问题: std::vector<bool> features(const Widget& w); // OK ]; processWidget(w, highPriority); // ERROR auto highPriority = features(w)[]; processWidget(w, highPriority); // undefined…
条款5 相对显式类型声明,更倾向使用auto 基础知识 auto能大大方便变量的定义,可以表示仅由编译器知道的类型. template<typename It> void dwim(It b, It e) { while(b != e) { //typename std::iterator_traits<It>::value_type currValue = *b; // old type auto currValue = *b; // new type } } auto可以用来定…
条款三 了解decltype 基础知识 提供一个变量或者表达式,decltype会返回其类型,但是返回的内容会使人感到奇怪. 以下是一些简单的推断类型: ; // decltype(i) -> const int bool f(const Widget& w); // decltype(w) -> const Widget&, decltype(f) -> bool(const Widget&) struct Point { int x, y; } // decl…
条款2: 理解auto自己主动类型推导 假设你已经读过条款1关于模板类型推导的内容,那么你差点儿已经知道了关于auto类型推导的所有. 至于为什么auto类型推导就是模板类型推导仅仅有一个地方感到好奇.那是什么呢?即模板类型推导包含了模板.函数和參数,而auto类型判断不用与这些打交道. 这当然是真的.可是没关系. 模板类型推导和auto自己主动类型推导是直接匹配的. 从字面上看,就是从一个算法转换到还有一个算法而已. 在条款1中.阐述模板类型推导採用的是常规的函数模板: template<ty…
第一章 类型推导 C++98有一套单一的类型推导的规则:用来推导函数模板,C++11轻微的修改了这些规则并且增加了两个,一个用于auto,一个用于decltype,接着C++14扩展了auto和decltype可以使用的语境,类型推导的普遍应用将程序员从必须拼写那些显然的,多余的类型的暴政中解放了出来,它使得C++开发的软件更有弹性,因为在某处改变一个类型会自动的通过类型推导传播到其他的地方. 然而,它可能使产生的代码更难观察,因为编译器推导出的类型可能不像我们想的那样显而易见. 想要在现代C+…
    在概念上说,auto关键字和它看起来一样简单,但是事实上,它要更微妙一些的.使用auto会让你在声明变量时省略掉类型,同时也会防止了手动类型声明带来的正确性和性能上的困扰:虽然按照语言预先定义的规则,一些auto类型推导的结果,在程序员的视角来看却是难以接受的,在这种情况下,知道auto是如何推导答案便是非常重要的事情,因为在所有可选方法中,你可能会回归到手动的类型声明上(because falling back on manual type declarations is an alt…
说起decltype,这是个古灵精怪的东西.对于给定的名字或表达式,decltype能告诉你该名字或表达式的型别.一般来说,它告诉你的结果和你预测的是一样的.不过,偶尔它也会给出某个结果,让你抓耳挠腮,不得不 去参考手册或在线FAQ页面求得一些启发. 先从一般案例讲起——就是那些不会引发意外的案例.与模板和auto的型别推导过程相反,decltype一般只会鹦鹉学舌,返回给定的名字或表达式的确切型别而已: ; //decltype(i)是const int bool f(const Widget…
在条款1中,我们已经了解了有关模板型别的推导的一切必要知识,那么也就意味着基本上了解了auto型别推导的一切必要知识. 因为,除了一个奇妙的例外情况,auto型别推导就是模板型别推导.尽管和模板型别推导打交道的是模板.函数和形参,auto和它们秋毫无犯,但并不影响上面的结论成立. 在条款1中,我们用来解释模板型别推导的函数模板形如: template<typename T> void f(ParamType param); 而一次调用形如: f(expr); //以某表达式调用f 在f的调用语…
成百上千的程序员都在向函数模板传递实参,并拿到了完全满意的结果,而这些程序员中却有很多对这些函数使用的型别是如何被推导出的过程连最模糊的描述都讲不出来. 但是当模板型别推导规则应用于auto语境时,它们不像应用于模板时那样符合直觉.所以了解作为auto基础的模板型别推导的方方面面就变得相当重要了. 本条款将说明这些推导过程.这里通过一段伪代码来说明,函数模板大致形如: template<typename T> void f(ParamType param); 而一次调用形如: f(expr);…
41:针对可复制的形参,在移动成本低且一定会被复制的前提下,考虑将其按值传递 class Widget { public: void addName(const std::string& newName) { names.push_back(newName); } void addName(std::string&& newName) { names.push_back(std::move(newName)); } … private: std::vector<std::st…
C++11的志伟功勋之一,就是将并发融入了语言和库中,因此在C++的历史上,程序员可以首次跨越所有平台撰写具有标准行为的多线程程序. 35:优先选用基于任务而非基于线程的程序设计 如果需要以异步的方式运行函数doAsyncWork,有两种选择,基于线程的方法(使用std::thread)和基于任务(使用std::async)的方法: int doAsyncWork(); std::thread t(doAsyncWork); auto fut = std::async(doAsyncWork);…
移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引用是将这两个不相关的语言特性连接起来的底层语言机制,正是它使得移动语义和完美转发成了可能. 23:理解std::move和std::forward std::move并不进行任何移动,std::forward也不进行任何转发.这两者在运行期都无所作为,它们不会生成任何可执行代码.实际上,std::m…
05:优先使用auto,而非显示类型声明 显示类型声明有下面一些缺点: int x; //未初始化,或者初始化为0,视语境而定 template<typename It> void dwim(It b, It e) { while (b != e) { typename std::iterator_traits<It>::value_type //啰嗦 currValue = *b; … } } 另外,如果想要使用闭包的类型来声明变量,但是闭包的类型只有编译器知道. 有了auto之…
类的代理对象 其实这部分内容主要是说明了在STL或者某些其他代码的容器中,在一些代理类的作用下使得最后的返回值并不是想要的结果. 而他的返回值则是类中的一个容器,看下面的一段代码: std::vector<bool> Boolen(const Sign& w);//返回值为vector<bool>的函数 Signed a; bool b = Boolen(a)[3]://返回值为 vector<bool>& auto c = Boolen(a)[3];/…
条款2.理解auto型别推导 对于auto的型别推导而言,其中大部分情况和模板型别推导是一模一样的.只有一种特例情况. 我们先针对auto和模板型别推导一致的情况进行讨论: //某变量采用auto来声明的时候,其中auto就扮演了模板中的T这个角色,而变量的型别修饰词则对应函数形参paramauto x = 27;//其中T对应auto.param也对应autoconst auto cx = x;//T对应auto,param对应const autoconst auto& rx = x; //p…
Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understand decltype. Item 4: Know how to view deduced types. Item 5: Prefer auto to explicit type declarations. Item 6: Use the explicitly typed initializer i…
条款7 辨别使用()与{}创建对象的差别 基础知识 目前已知有如下的初始化方式: ); ; }; }; // the same as above 在以“=”初始化的过程中没有调用赋值运算,如下例所示: Widget w1; // default ctor Widget w2 = w1; // copy ctor w1 = w2; // assignment, operator = 还可以用来初始化: class Widget { }; // fine ; // fine ); // error…
条款四 知道如何看待推断出的类型 基础知识 有三种方式可以知道类型推断的结果: IDE编辑器 编译器诊断 运行时输出 使用typeid()以及std::type_info::name可以获取变量的类型信息,但是存在一些问题,代码如下: template<typename T> void f(const T& param) { using std::cout; cout << "T = " << typeid(T).name() <<…