本身翻译着玩的,尽可能简单易记,书仍是要看的,这个作为一个提纲没事看看。c++
CHAPTER 1 Deducing Types
章节1 类型推导
Item 1:Understand template type deduction.
条款1:理解模板类型推导.
Things to Remember
须要记住:express
- During template type deduction, arguments that are references are treated as non-references, i.e., their reference-ness is ignored.
- 推导模版类型时,引用的值视为非引用,即忽略引用。
- When deducing types for universal reference parameters, lvalue arguments get special treatment.
- 推导通用引用类型参数时,左值特殊处理。
- When deducing types for by-value parameters, const and/or volatile arguments are treated as non-const and non-volatile.
- 推导传值参数时,忽略const和volatile。
- During template type deduction, arguments that are array or function names decay to pointers, unless they’re used to initialize references.
- 推导模版类型时,参数是数组或函数名则退化为指针,除非用来初始化引用。
Item 2:Understand auto type deduction.
条款2:理解auto类型推导.
Things to Remember
须要记住:编程
- auto type deduction is usually the same as template type deduction, but auto type deduction assumes that a braced initializer represents a std::initializer_list, and template type deduction doesn’t.
- 推导auto类型通常和推导模版类型是一致的,但auto类型推导对于大括号初始化{}会推导为std::initializer_list,模版类型推导则不会。
- auto in a function return type or a lambda parameter implies template type deduction, not auto type deduction.
- 作为函数返回类型或lambda参数中的auto类型推导意味着模版类型推导,而不作为auto类型推导。
Item 3:Understand decltype.
条款3:理解decltype.
Things to Remember
须要记住:api
- decltype almost always yields the type of a variable or expression without any modifications.
- decltype几乎老是推导出变量或表达式的类型,不作任何修改。
- For lvalue expressions of type T other than names, decltype always reports a type of T&.
- 类型为T的左值表达式而不是名称,decltype老是推导成引用T&。
- C++14 supports decltype(auto), which, like auto, deduces a type from its initializer, but it performs the type deduction using the decltype rules.
- C++14支持decltype(auto),和auto同样,经过初始值推导,但使用decltype规则。
Item 4:Know how to view deduced types.
条款4:知道如何查看推导出来的类型.
Things to Remember
须要记住:数组
- Deduced types can often be seen using IDE editors, compiler error messages, and the Boost TypeIndex library.
- 推导出来的类型一般可使用IDE编辑器,编译错误信息或Boost TypeIndex库查看到。
- The results of some tools may be neither helpful nor accurate, so an understanding of C++’s type deduction rules remains essential.
- 有些工具查看到的结果可能没有任何帮助或者就是错误的,因此理解类型推导规则仍是有用的。
CHAPTER 2 auto
章节2 auto
Item 5:Prefer auto to explicit type declarations.
条款5: 优先使用auto,而不是显式的类型声明
Things to Remember
须要记住:promise
- auto variables must be initialized, are generally immune to type mismatches that can lead to portability or efficiency problems, can ease the process of refactoring, and typically require less typing than variables with explicitly specified types.
- auto变量必须初始化,基本上不会有类型不匹配致使的可移值问题或效率问题的影响,也能够简化重构过程,通常也比显式指定类型须要更少的键盘输入。
- auto-typed variables are subject to the pitfalls described in Items 2 and 6.
- auto类型的变量请查看条款2和条款6中描述的陷阱。
Item 6:Use the explicitly typed initializer idiom when auto deduces undesired types.
条款6:当auto推导出的类型不是想要的类型时,使用显示类型初始化的惯用语法。
Things to Remember
须要记住:缓存
- “Invisible” proxy types can cause auto to deduce the “wrong” type for an initializing expression.
- “不可见的”代理类型会致使auto对初始化表达式推导出“错误的”类型。
- The explicitly typed initializer idiom forces auto to deduce the type you want it to have.
- 显示类型初始化的惯用语法迫使auto推导出想要的类型。
CHAPTER 3 Moving to Modern C++
章节3 迁移到现代C++
Item 7:Distinguish between () and {} when creating objects.
条款7:建立对象时区分()和{}。
Things to Remember
须要记住:安全
- Braced initialization is the most widely usable initialization syntax, it prevents narrowing conversions, and it’s immune to C++’s most vexing parse.
- 花括号初始化方法是最为普遍使用的初始化语法,能够防止类型转换变窄,也不受C++烦人的解析问题影响。
- During constructor overload resolution, braced initializers are matched to std::initializer_list parameters if at all possible, even if other constructors offer seemingly better matches.
- 构造函数的重载解析中,花括号初始化方法只要可能就会匹配std::initializer_list参数,即便有其它的构造函数提供了看上去更好的匹配参数。
- An example of where the choice between parentheses and braces can make a significant difference is creating a std::vector
with two arguments.
- std::vector <数字类型> 在使用圆括号和花括号初始化时意义彻底不一样。
- Choosing between parentheses and braces for object creation inside templates can be challenging.
- 在模板中的对象建立时选择圆括号仍是花括号是一个挑战。
Item 8: Prefer nullptr to 0 and NULL.
条款8:优先使用nullptr,而不是0和NULL。
Things to Remember
须要记住:多线程
- Prefer nullptr to 0 and NULL.
- 优先使用nullptr,而不是0和NULL。
- Avoid overloading on integral and pointer types.
- 避免整形或指针类型的重载。
Item 9:Prefer alias declarations to typedef s.
条款9:优先使用alias声明,而不是typedef。
Things to Remember
须要记住:
- typedefs don’t support templatization, but alias declarations do.
- typedefs不支持模板化,alias声明支持。
- Alias templates avoid the “::type” suffix and, in templates, the “typename” prefix often required to refer to typedefs.
- alias模板避免了“::type”后缀,以及在模板中的用于typedefs的“typename”前缀。
- C++14 offers alias templates for all the C++11 type traits transformations.
- 全部C++11中类型traits转换,C++14都提供了alias模板。
Item 10:Prefer scoped enum s to unscoped enum s.
条款10:优先使用范围枚举,而不是非范围枚举。
Things to Remember
须要记住:
- C++98-style enums are now known as unscoped enums.
- C++98类型的枚举就是非范围枚举。
- Enumerators of scoped enums are visible only within the enum. They convert to other types only with a cast.
- 范围枚举的枚举器只在枚举内部可见,只能经过cast转换为其它类型。
- Both scoped and unscoped enums support specification of the underlying type. The default underlying type for scoped enums is int. Unscoped enums have no default underlying type.
- 范围枚举和非范围枚举都支持指定底层类型。范围枚举的默认底层类型是int, 而非范围没有默认底层类型。
- Scoped enums may always be forward-declared. Unscoped enums may be forward-declared only if their declaration specifies an underlying type.
- 范围枚举老是能够前向声明,而非范围枚举只有指定底层类型时才能够前向声明。
Item 11:Prefer deleted functions to private undefined ones.
条款11:优先使用deleted函数,而不是私有未定义函数。
Things to Remember
须要记住:
- Prefer deleted functions to private undefined ones.
- 优先使用deleted函数,而不是私有未定义函数。
- Any function may be deleted, including non-member functions and template instantiations.
- 任何函数均可以deleted, 包括非成员函数和模板实例函数。
Item 12:Declare overriding functions override
条款12:把重写函数声明为override
Things to Remember
须要记住:
- Declare overriding functions override.
- 把重写函数声明为override
- Member function reference qualifiers make it possible to treat lvalue and rvalue objects (*this) differently.
- 成员函数引用限定符能够区别对待左值和右值对象。
Item 13:Prefer const_iterator s to iterator s.
条款13:优先使用const_iterator, 而不是其它的iterator。
Things to Remember
须要记住:
- Prefer const_iterators to iterators.
- 优先使用const_iterator, 而不是其它的iterator。
- In maximally generic code, prefer non-member versions of begin, end, rbegin, etc., over their member function counterparts.
- 大多数泛型代码中,优先使用非成员函数版本的begin, end, rbegin等等,而不是相应的成员函数。
Item 14:Declare functions noexcept if they won’t emit exceptions.
条款14:若是函数不抛出异常则声明为noexcept
Things to Remember
须要记住:
- noexcept is part of a function’s interface, and that means that callers may depend on it.
- noexcept是函数接口的一部分,意味着调用者必须依赖它。
- noexcept functions are more optimizable than non-noexcept functions.
- noexcept函数更容易优化。
- noexcept is particularly valuable for the move operations, swap, memory deallocation functions, and destructors.
- noexcept在移动操做,交换,内存释放函数,析构函数中特别有价值。
- Most functions are exception-neutral rather than noexcept.
- 大多数函数是异常中立的,而不是noexcept。
Item 15:Use constexpr whenever possible.
条款15:只要有可能就使用constexpr。
Things to Remember
须要记住:
- constexpr objects are const and are initialized with values known during compilation.
- constexpr对象是常量而且是在编译期初始化的。
- constexpr functions can produce compile-time results when called with arguments whose values are known during compilation.
- constexpr函数在给定的参数是编译期已知的状况下能够生成编译期结果。
- constexpr objects and functions may be used in a wider range of contexts than non-constexpr objects and functions.
- constexpr对象和函数比起非constexpr对象和函数,可使用在更宽泛的上下文范围。
- constexpr is part of an object’s or function’s interface.
- constexpr是对象接口或函数接口的一部分。
Item 16:Make const member functions thread safe.
条款16:使const成员成为线程安全的。
Things to Remember
须要记住:
- Make const member functions thread safe unless you’re certain they’ll never be used in a concurrent context.
- 除非肯定不会在并发环境中使用,不然const成员必定要是线程安全的。
- Use of std::atomic variables may offer better performance than a mutex, but they’re suited for manipulation of only a single variable or memory location.
- std::atomic变量比mutex性能更好,但只能用于操做单一变量或单一内存位置。
Item 17:Understand special member function generation.
条款17:理解特殊成员函数的生成。
Things to Remember
须要记住:
- The special member functions are those compilers may generate on their own: default constructor, destructor, copy operations, and move operations.
- 特殊成员函数就是编译器自动生成的:默认构造函数,析构函数,拷贝操做,移动操做。
- Move operations are generated only for classes lacking explicitly declared move operations, copy operations, and a destructor.
- 移动操做函数只有在没有显式声明移动操做,拷贝操做,析构函数时才会生成。
- The copy constructor is generated only for classes lacking an explicitly declared copy constructor, and it’s deleted if a move operation is declared. The copy assignment operator is generated only for classes lacking an explicitly declared copy assignment operator, and it’s deleted if a move operation is declared. Generation of the copy operations in classes with an explicitly declared destructor is deprecated.
- 拷贝构造函数只有在没有显式声明拷贝构造函数时才会生成,并且若是声明了移动操做就会被删除。拷贝赋值操做只有在没有显式声明拷贝赋值操做符才会生成,并且声明了移动操做就会删除。若是显式声明了析构函数,则拷贝操做就会过期。
- Member function templates never suppress generation of special member functions.
- 成员函数模板永远不会阻止特殊成员函数的生成。
CHAPTER 4 Smart Pointers
章节4 智能指针
Item 18:Use std::unique_ptr for exclusive-ownership resource management.
条款18:使用std::unique_ptr管理独占资源。
Things to Remember
须要记住:
- std::unique_ptr is a small, fast, move-only smart pointer for managing resources with exclusive-ownership semantics.
- std::unique_ptr小巧,快速,只能移动,用于管理独占资源。
- By default, resource destruction takes place via delete, but custom deleters can be specified. Stateful deleters and function pointers as deleters increase the size of std::unique_ptr objects.
- 默认状况下资源析构使用delete, 但能够指定自定义的删除器。有状态的删除器或函数指针会增长std::unique_ptr对象的大小。
- Converting a std::unique_ptr to a std::shared_ptr is easy.
- std::unique_ptr很容易转换为std::shared_ptr。
Item 19:Use std::shared_ptr for shared-ownership resource management.
条款19: 使用std::shared_ptr管理共享资源。
Things to Remember
须要记住:
- std::shared_ptrs offer convenience approaching that of garbage collection for the shared lifetime management of arbitrary resources.
- std::shared_ptrs对于随意的资源的共享生命周期管理提供方便的垃圾回收处理方法。
- Compared to std::unique_ptr, std::shared_ptr objects are typically twice as big, incur overhead for control blocks, and require atomic reference count manipulations.
- 相对于std::unique_ptr来讲,std::shared_ptr对象一般大一倍,主要是控制块,原子引用计数操做致使。
- Default resource destruction is via delete, but custom deleters are supported. The type of the deleter has no effect on the type of the std::shared_ptr.
- 默认资源的析构是经过delete, 但也支持自定义删除器。删除器的类型对std::shared_ptr的类型不起做用。
- Avoid creating std::shared_ptrs from variables of raw pointer type.
- 避免从原始指针类型的变量生成std::shared_ptrs。
Item 20:Use std::weak_ptr for std::shared_ptr - like pointers that can dangle.
条款20:使用std::weak_ptr代替可能会发生悬空指针的std::shared_ptr。
Things to Remember
须要记住:
- Use std::weak_ptr for std::shared_ptr-like pointers that can dangle.
- 使用std::weak_ptr代替可能会发生悬空指针的std::shared_ptr。
- Potential use cases for std::weak_ptr include caching, observer lists, and the prevention of std::shared_ptr cycles.
- 潜在的使用std::weak_ptr的情景有缓存,观察者列表,避免std::shared_ptr循环引用。
Item 21:Prefer std::make_unique and std::make_shared to direct use of new
条款21:优先使用std::make_unique和std::make_shared,而不是直接使用new。
Things to Remember
须要记住:
- Compared to direct use of new, make functions eliminate source code duplication, improve exception safety, and, for std::make_shared and std::allocate_shared, generate code that’s smaller and faster.
- 相对于直接使用new来讲,make函数消除了源代码重复,提高了异常安全,并且std::make_shared和std::allocate_shared都会生成更小更快的代码。
- Situations where use of make functions is inappropriate include the need to specify custom deleters and a desire to pass braced initializers.
- 不适合使用make函数的状况有指定自定义的删除器,须要传递括号初始化器。
- For std::shared_ptrs, additional situations where make functions may be ill-advised include (1) classes with custom memory management and (2) systems with memory concerns, very large objects, and std::weak_ptrs that outlive the corresponding std::shared_ptrs.
- 对std::shared_ptrs来讲,make函数不推荐使用的其它状况还有(1)有自定义内存管理的类(2)有内存问题的系统,很是大的对象,以及std::weak_ptrs比std::shared_ptrs的生命还要长的状况。
Item 22:When using the Pimpl Idiom, define special member functions in the implementation file.
条款22:若是使用Pimpl惯用法,则要在实现文件中定义特殊成员函数。
Things to Remember
须要记住:
- The Pimpl Idiom decreases build times by reducing compilation dependencies between class clients and class implementations.
- Pimpl惯用法经过减小类的实现和类的客户的编译依赖关系缩减了编译时间。
- For std::unique_ptr pImpl pointers, declare special member functions in the class header, but implement them in the implementation file. Do this even if the default function implementations are acceptable.
- 若是std::unique_ptr用于pImpl指针,则在类的头文件中声明特殊成员函数,在实现文件中实现。即便默认的函数实现能够接受的话也要这么作。
- The above advice applies to std::unique_ptr, but not to std::shared_ptr.
- 以上建议适用于std::unique_ptr,但不适用于std::shared_ptr。
CHAPTER 5 Rvalue References, Move Semantics, and Perfect Forwarding
章节5 右值引用,移动语义和完美转发
Item 23:Understand std::move and std::forward.
条款23: 理解std::move和std::forward。
Things to Remember
须要记住:
- std::move performs an unconditional cast to an rvalue. In and of itself, it doesn’t move anything.
- std::move无条件转换为右值,就其自己而言,它不移动任何东西。
- std::forward casts its argument to an rvalue only if that argument is bound to an rvalue.
- std::forward只有在绑定的参数是右值时才会将参数转换为右值。
- Neither std::move nor std::forward do anything at runtime.
- std::move和std::forward在运行时不作任何事情。
Item 24:Distinguish universal references from rvalue references.
条款24:区分通用引用和右值信引用。
Things to Remember
须要记住:
- If a function template parameter has type T&& for a deduced type T, or if an object is declared using auto&&, the parameter or object is a universal reference.
- 若是函数模板参数有类型T&&而且须要推导T,或者对象声明为auto&&, 则参数或对象是通用引用。
- If the form of the type declaration isn’t precisely type&&, or if type deduction does not occur, type&& denotes an rvalue reference.
- 若是类型声明的格式不是精确的type&&, 或不须要类型推导,type&&就是右值引用。
- Universal references correspond to rvalue references if they’re initialized with rvalues. They correspond to lvalue references if they’re initialized with lvalues.
- 通用引用若是使用右值初始化的话,则和右值引用是一致的。若是是用左值初始化的话,则与左值引用是一致的。
Item 25:Use std::move on rvalue references, std::forward on universal references.
条款25:对右值引用使用std::move, 对通用引用使用std::forward。
Things to Remember
须要记住:
- Apply std::move to rvalue references and std::forward to universal references the last time each is used.
- 最后一次使用时,对右值引用使用std::move, 对通用引用使用std::forward。
- Do the same thing for rvalue references and universal references being returned from functions that return by value.
- 返回值是传值时,同上面同样。
- Never apply std::move or std::forward to local objects if they would otherwise be eligible for the return value optimization.
- 若是本地对象有可能作返回值优化的话,永远也不要对本地对象使用std::move或std::forward。
Item 26:Avoid overloading on universal references.
条款26:避免对通用引用进行重载。
Things to Remember
须要记住:
- Overloading on universal references almost always leads to the universal reference overload being called more frequently than expected.
- 重载通用引用几乎老是超预期地频繁调用了通用引用的重载。
- Perfect-forwarding constructors are especially problematic, because they’re typically better matches than copy constructors for non-const lvalues, and they can hijack derived class calls to base class copy and move constructors.
- 完美转发构造函数特别有问题,由于比non-const左值的拷贝构造函数有更好的匹配,这样就会派生类调用基类的拷贝构造函数和移动构造函数。
Item 27:Familiarize yourself with alternatives to overloading on universal references.
条款27:熟悉重载通用引用函数的其它替代方法
Things to Remember
须要记住:
- Alternatives to the combination of universal references and overloading include the use of distinct function names, passing parameters by lvalue-reference-to-const, passing parameters by value, and using tag dispatch.
- 通用引用和重载的组合的替代方法有使用不一样的函数名,经过常量的左值引用传递参数,经过值传递参数,以及使用标记调度。
- Constraining templates via std::enable_if permits the use of universal references and overloading together, but it controls the conditions under which compilers may use the universal reference overloads.
- 经过std::enable_if约束模板能够容许通用引用和重载一块儿使用,但会控制编译器使用通用引用重载的条件。
- Universal reference parameters often have efficiency advantages, but they typically have usability disadvantages.
- 通用引用参数常常会有提高效率的优势,可是一般也会有使用上的缺点。
Item 28:Understand reference collapsing.
条款28:理解引用折叠。
Things to Remember
须要记住:
- Reference collapsing occurs in four contexts: template instantiation, auto type generation, creation and use of typedefs and alias declarations, and decltype.
- 引用折叠发生在四种状况:模板实例化,自动类型生成,typedef和alias声明的建立和使用,decltype。
- When compilers generate a reference to a reference in a reference collapsing context, the result becomes a single reference. If either of the original references is an lvalue reference, the result is an lvalue reference. Otherwise it’s an rvalue reference.
- 当编译器在引用折叠环境中生成引用的引用时,结果就会成为单引用。若是原始的引用有一个是左值引用,则结果就是左值引用,不然就是右值引用。
- Universal references are rvalue references in contexts where type deduction distinguishes lvalues from rvalues and where reference collapsing occurs.
- 通用引用是右值引用的状况有,类型推导能够区分左值和右值时,以及发生引用折叠时。
Item 29:Assume that move operations are not present, not cheap, and not used.
条款29: 要假定移动操做是不存在在,不是廉价的,也不是可用的。
Things to Remember
须要记住:
- Assume that move operations are not present, not cheap, and not used.
- 要假定移动操做是不存在在,不是廉价的,也不是可用的。
- In code with known types or support for move semantics, there is no need for assumptions.
- 已知类型或支持移动语义类型的代码中,不须要有假定。
Item 30:Familiarize yourself with perfect forwarding failure cases.
条款20:熟悉完美转发失败案例。
Things to Remember
须要记住:
- Perfect forwarding fails when template type deduction fails or when it deduces the wrong type.
- 若是模板类型推导失败或推导出错误的类型时,完美转发就会失败。
- The kinds of arguments that lead to perfect forwarding failure are braced initializers, null pointers expressed as 0 or NULL, declaration-only integral const static data members, template and overloaded function names, and bitfields.
- 致使完美转发失败的参数类型有括号初始化器,使用0或NULL的指针,整形常量静态数据成员的声明,模板和重载函数名称,位成员。
CHAPTER 6 Lambda Expressions
章节6 Lambda表达式
Item 31:Avoid default capture modes.
条款31:避免默认的捕捉模式。
Things to Remember
须要记住:
- Default by-reference capture can lead to dangling references.
- 默认的传引用操做捕捉会致使悬空引用。
- Default by-value capture is susceptible to dangling pointers (especially this), and it misleadingly suggests that lambdas are self-contained.
- 默认的传值操做捕捉容易受悬空指针影响(特别是这里),而且会误导成lambdas是自包含的。
Item 32:Use init capture to move objects into closures.
条款32:使用init捕捉来移动对象到闭包。
Things to Remember
须要记住:
- Use C++14’s init capture to move objects into closures.
- 使用c++14的init捕捉来移动对象到闭包。
- In C++11, emulate init capture via hand-written classes or std::bind.
- C++11中,经过手写的类或std::bind来模仿init捕捉。
Item 33:Use decltype on auto&& parameters to std::forward them.
条款33:使用decltype调用std::forward移动auto&&参数。
Things to Remember
须要记住:
- Use decltype on auto&& parameters to std::forward them.
- 使用decltype调用std::forward移动auto&&参数。
Item 34:Prefer lambdas to std::bind
条款34:优先使用lambdas,而不是std::bind
Things to Remember
须要记住:
- Lambdas are more readable, more expressive, and may be more efficient than using std::bind.
- Lambdas更容易阅读,更快捷,而且比std::bind更高效。
- In C++11 only, std::bind may be useful for implementing move capture or for binding objects with templatized function call operators.
- 只有在C++11中,std::bind在实现移动捕捉或绑定对象到模板化的函数调用操做符上可能会有用。
CHAPTER 7 The Concurrency API
章节7 并发API
Item 35:Prefer task-based programming to thread-based.
条款35:优先采用基于task的编程方法,而不是基于thread(相关的类)。
Things to Remember
须要记住:
- The std::thread API offers no direct way to get return values from asynchronously run functions, and if those functions throw, the program is terminated.
- std::thread API从异步运行函数中获得非直接的结果,若是函数抛出异常,则程序终止。
- Thread-based programming calls for manual management of thread exhaustion, oversubscription, load balancing, and adaptation to new platforms.
- 基于Thread的编程方法调用须要手工管理线程耗尽、过分订阅、负载均衡,以及适应新平台等问题。
- Task-based programming via std::async with the default launch policy handles most of these issues for you.
- 基于Task的编程方法经过std::async使用默认加载策略来处理大多数的问题。
Item 36:Specify std::launch::async if asynchronicity is essential.
条款36:若是须要异步处理,请指定std::launch::async。
Things to Remember
须要记住:
- The default launch policy for std::async permits both asynchronous and synchronous task execution.
- std::async的默认加载策略既容许异步执行,也容许同步的执行。
- This flexibility leads to uncertainty when accessing thread_locals, implies that the task may never execute, and affects program logic for timeout-based wait calls.
- 灵活性也会致使访问thread_local时产生不肯定性,线程也许永远不会执行,也会影响基于超时等待调用的程序逻辑。
- Specify std::launch::async if asynchronous task execution is essential.
- 若是须要异步处理,请指定std::launch::async。
Item 37:Make std::threads unjoinable on all paths.
条款37:使std::threads在任何路径下都是不能join的。
Things to Remember
须要记住:
- Make std::threads unjoinable on all paths.
- 使std::threads在任何路径下都是不能join的。
- join-on-destruction can lead to difficult-to-debug performance anomalies.
- 在析构函数上join会致使难以调试的性能问题。
- detach-on-destruction can lead to difficult-to-debug undefined behavior.
- 在析构函数上detach会致使难以调试的未定义行为。
- Declare std::thread objects last in lists of data members.
- 将std::thread对象作为数据成员列表项中的最后一个。
Item 38:Be aware of varying thread handle destructor behavior.
条款38:要当心不一样的线程句柄析构行为。
Things to Remember
须要记住:
- Future destructors normally just destroy the future’s data members.
- Future的析构函数一般只会销毁future的数据成员。
- The final future referring to a shared state for a non-deferred task launched via std::async blocks until the task completes.
- 涉及到非延期task的共享状态的final future是经过std::async,在task完成后加载的。
Item 39:Consider void futures for one-shot event communication.
条款39: 考虑对于一次性事件通讯中使用void future。
Things to Remember
须要记住:
- For simple event communication, condvar-based designs require a superfluous mutex, impose constraints on the relative progress of detecting and reacting tasks, and require reacting tasks to verify that the event has taken place.
- 对于简单的事件通讯,基于condvar的设计须要一个多余的互斥量,对检测和响应任务的相应进度施加限制,而且须要响应任务验证事件是否已发生。
- Designs employing a flag avoid those problems, but are based on polling, not blocking.
- 设计使用一个标记来避免这些问题,但这是基于轮询的,而不是基于阻塞的。
- A condvar and flag can be used together, but the resulting communications mechanism is somewhat stilted.
- condvar和标记能够一块儿使用,但结果通讯机制会有点不天然。
- Using std::promises and futures dodges these issues, but the approach uses heap memory for shared states, and it’s limited to one-shot communication.
- 使用std::promises和futures来回避这些问题,可是这种方法使用堆内存来处理共享状态,而且只能用于一次性通讯。
Item 40:Use std::atomic for concurrency, volatile for special memory.
条款40:使用std::atomic处理并发,使用volatile处理特殊内存。
Things to Remember
须要记住:
- std::atomic is for data accessed from multiple threads without using mutexes. It’s a tool for writing concurrent software.
- std::atomic用来在不使用mutex的多线程情形下访问数据。它是编写并发软件的一个工具。
- volatile is for memory where reads and writes should not be optimized away. It’s a tool for working with special memory.
- volatile用来在读写操做不是优化的方式下处理内存。它是编写处理特殊内存的一个工具。
CHAPTER 8 Tweaks
章节8 小改进
Item 41:Consider pass by value for copyable parameters that are cheap to move and always copied.
条款41: 考虑使用传值来处理移动操做很廉价并且老是被拷贝的参数(若是移动没有提升性能的话,编译器可能就直接优化成拷贝了)
Things to Remember
须要记住:
- For copyable, cheap-to-move parameters that are always copied, pass by value may be nearly as efficient as pass by reference, it’s easier to implement, and it can generate less object code.
- 对于可以拷贝,移动操做很廉价并且老是被拷贝的参数,传值跟传引用基本上一样高效,并且更容易实现,产生更少的代码。
- Copying parameters via construction may be significantly more expensive than copying them via assignment.
- 经过构造函数拷贝参数可能比经过赋值操做符拷贝参数更加高昂。
- Pass by value is subject to the slicing problem, so it’s typically inappropriate for base class parameter types.
- 传值操做会有切片问题,因此通常对于基类参数类型不适合。
Item 42:Consider emplacement instead of insertion.
条款42:考虑使用emplace的函数,而不是insert函数
Things to Remember
须要记住:
- In principle, emplacement functions should sometimes be more efficient than their insertion counterparts, and they should never be less efficient.
- 原则上,emplace的函数有时应该比插入函数效率更高,并且效率永远不会下降。
- In practice, they’re most likely to be faster when (1) the value being added is constructed into the container, not assigned; (2) the argument type(s) passed differ from the type held by the container; and (3) the container won’t reject the value being added due to it being a duplicate.
- 在实践中,如下情形(emplace的函数)可能更快:(1)要添加的值是构造到容器中时,而不是赋值到容器中(2)传递的参数类型与容器中的类型不一样(3)容器不会排斥要添加的值,由于它是重复的值。
- Emplacement functions may perform type conversions that would be rejected by insertion functions.
- Emplace的函数有可能执行类型转换,而insert的函数会排斥。