In recent talks (e.g., at Going Native in February and at Lang.Next earlier this month), Herb has offered guidelines for proper usage of C++11.  He made it look so easy, I said to myself, “Heck, I could do that.”  Besides, people have been pestering me about a new edition of Effective C++, so I figured I’d sit down and try to come up with a few prospective guidelines.  “How hard can it be?,” I asked myself.

Easier than expected, actually.  In about a half hour, I’d jotted down some 25 candidate guidelines.  That’s more than enough for a meaty C&B talk, so I plan to give one.  What will be in the talk?  I don’t know yet, because what I have are prospective guidelines, and they will evolve as I work on them and as I learn more about C++11 and its effective application. (My knowledge continues to change almost daily.) What follows is a snapshot of the list of candidate guidelines I have right now.  The ordering is random, and the wording is tentative, so don’t read too much into them.  There are far more here than can be covered in single talk, so there’s no way I’ll cover all of these at C&B.  My plan is to focus on the ones I think include material that is particularly important or particularly surprising (e.g., counterintuitive). If you see a topic you’d like to hear about, please post a comment to that effect.  If you don’t see a topic you think I should address, please post about that.  If you see a guideline you think is bad advice, posting a comment is again the thing to do.  If you know of a good guideline you don’t see listed, post, post, post!


  • Prefer auto to Explicit Type Declarations
  • Distinguish () and {} When Creating Objects
  • Remember that auto + { expr } == std::initializer_list
  • Prefer non-member begin/end to member versions
  • Declare std::thread Members Last in Classes
  • Be Wary of Default Capture Modes in Lambdas Escaping Member Functions
  • Prefer Emplacement to Insertion
  • Pass std::launch::async if Asynchronicity is Essential
  • Minimize use of Weak Atomics
  • Distinguish Rvalue References from Universal References
  • Assume that move operations are neither present nor cheap
  • Prefer Lambdas over Binders
  • Prefer Lambdas over Variadic Arguments to Threading Functions
  • Be Wary of Oversubscription
  • Apply std::forward when Passing Universal References
  • Prefer std::array to Built-in Arrays
  • Use std::make_shared Whenever Possible
  • Prefer Pass-by-Reference-to-const to Pass-by-Value for std::shared_ptrs
  • Pass by Value if You’ll Copy Your Parameter
  • Reserve noexcept for Functions with Wide Interfaces
  • For Copyable Types, View Move as an Optimization of Copy
  • Prefer enum classes to enums
  • Prefer nullptr to NULL and 0
  • Distinguish among std::enable_if, static_assert, and =delete