本身翻譯着玩的,儘可能簡單易記,書仍是要看的,這個作爲一個提綱沒事看看。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的函數會排斥。