The Evolving Search for Effective C++ Scott Meyers Image Florian Wizorek. Used with permission. Last Revised: 12/5/14 1991 1991 1995 1997 1999 2001 2005 2014 Polar Bear Image: Polar Bear Cub, tableatny @ flickr Slide 2
Information Information Information Information Information Information Information Information
Effective Effective Books 1. Keep Items short. 2. Put Item titles in the imperative. 3. Make Item advice as specific as possible 4. Word Item titles carefully. 5. Prefer guidelines that say what to do over what not to do. 6. Tell the truth and nothing but the truth, but not necessarily the whole truth. 7. Back Items with solid technical arguments. 8. End each Item with a summary of its advice. 9. Know how to modulate the stridency of Item titles. 10. Cross reference liberally. 11. Minimize use of footnotes. 12. Be consistent when referring to yourself and your readers. 13. Seek out ruthless pre-publication reviewers. Slide 5 Case Study Item 42 Slide 6
Candidate Guideline Prefer emplacement to insertion. Slide 7 Emplacement vs. Insertion for Container<T> Insertion functions take parameters of type (reference to) T: push_front(t) push_back(t) insert(position, T) insert_after(position, T) Emplacement functions take constructor arguments for T: emplace_front(ctor args for T) emplace_back(ctor args for T) emplace(position, ctor args for T) emplace_hint(position, ctor args for T) emplace_after(position, ctor args for T) In std::vector<std::string>: void push_back(const std::string&); void push_back(std::string&&); template<class... Args> void emplace_back(args&&...); Slide 8
The Case for Emplacement Avoids temporary creation: std::vector<std::string> vs; vs.push_back("xyzzy"); vs.emplace_back("xyzzy"); // create temp // move temp into vector // destroy temp // create string inside vector Slide 9 The Case for Emplacement For copyable/movable types, emplacement can do it all! std::string queenofdisco("donna Summer"); vs.push_back(queenofdisco); // copy-construct queenofdisco // at end of vs vs.emplace_back(queenofdisco); // ditto Ergo: Prefer emplacement to insertion. Should never be slower, should sometimes be faster. Right? Slide 10
Reality Check Howard Hinnant s experiments adding a T object to front of 3-element std::vector<t>. Two cases: Reallocation unnecessary (capacity > size). Reallocation required (capacity == size). For each case: Add lvalue. Add xvalue (e.g., std::move(existing object)). Add prvalue (e.g., T(ctor args)). Three std::vector implementations: libc++ (LLVM) libstdc++ (Gnu) VS2013 (Microsoft) Slide 11 Reallocation Unnecessary Results (Functions Executed per insert/emplace) Lvalue Xvalue Prvalue I E I I - - I - - libc++ libstdc++ VS2013 libc++ libstdc++ VS2013 libc++ libstdc++ VS2013 Reallocation Required - - I - - - - - - Slide 12
Observations Much variation per scenario or implementation: Number of functions executed. Whether insertion or emplacement executes fewer functions. Whether emplacement equivalent to insertion. Slide 13 Insight Construction fundamentally different from assignment: Construction can take arbitrary types. Assignment generally takes same-type argument. class Widget { public: Widget(int x, double d, std::string s); // arbitrary types Widget& operator=(const Widget&); // signatures per Widget& operator=(widget&&); // convention }; Seeming exceptions may not really be exceptional: template<typename chart> // simplified version class basic_string { public: basic_string& operator=(const chart* s); // specified as... // *this = basic_string(s) }; Slide 14
Insight Assignment for T generally requires argument of type T. Typically negates emplacement s performance advantage! So emplace_back may beat push_back, ditto for emplace_front, but no reason to expect emplace to normally beat insert. construction construction assignment Slide 15 Conclusions So Far Emplacement into a Container<T> a potential win only when: Object added to container via construction, not assignment. For std::vector/std::deque, true only for push_back/push_front. Multiple arguments passed. Avoids need to create temporary to satisfy insertion interface. Single argument passed not of type T. No reason to expect emplacing a T to beat inserting a T. Slide 16
CWUK = Containers with Unique Keys std::set<k>, std::unordered_set<k> have nodes holding K objects. CWUK Containers std::map<k, V>, std::unordered_map<k, V> have nodes holding std::pair<const K, V> objects. K (K,V) K K K K K (K,V) (K,V) (K,V) (K,V) (K,V) K K K K (K,V) (K,V) (K,V) (K,V) Slide 17 CWUK Container Declarations template <class Key, class Compare = less<key>, class Allocator = allocator<key> > class set; template <class Key, class Hash = hash<key>, class Pred = std::equal_to<key>, class Alloc = std::allocator<key> > class unordered_set; template <class Key, class T, class Compare = less<key>, class Allocator = allocator<pair<const Key, T> > > class map; From C++14 Standard template <class Key, class T, class Hash = hash<key>, class Pred = std::equal_to<key>, class Alloc = std::allocator<std::pair<const Key, T> > > class unordered_map; Slide 18
CWUK Containers Default same value comparisons are homogeneous: std::less<k> compares two K objects. std::equal_to<k> compares two K objects. Emplacement must create a K for comparison, even if value to be added is a duplicate. If a duplicate, created K must then be destroyed. No reason to expect emplacement to run faster than insertion: A temp object likely created to satisfy comparison function interface. Slide 19 CWUK Container Lookup Behavior Insertion: 1. Compare parameter key to keys in container. 2. If parameter key isn t in container, a. Dynamically allocate new node. b. Copy or move parameter key into new node. c. Link new node into container. For duplicate keys: No node allocation/deallocation. No copying or moving parameter key. Emplacement: 1. Dynamically allocate memory for new node. 2. Construct key in new node. 3. Compare new node key to keys in container. 4. If new node key isn t in container, a. link new node into container. else b. Destroy new node. For duplicate keys: Node allocated and deallocated. Key in new node constructed + destructed. Slide 20
Additional Conclusion Emplacement into a Container<T> a likely lose (vis-a-vis insertion) when: Container rejects duplicate keys and duplicate keys aren t uncommon. Slide 21 Consider: std::vector<std::regex> regexes; The Conversion Consideration regexes.push_back(nullptr); regexes.emplace_back(nullptr); Huh? // error! nullptr isn't a std::regex // and there's no implicit conversion // compiles! Slide 22
The Constructor in Question template <class chart, class traits = regex_traits<chart> > class basic_regex {... explicit basic_regex(const chart* p, flag_type f = regex_constants::ecmascript);... }; Requires: p shall not be a null pointer. From C++14 Standard Hence: regexes.emplace_back(nullptr); // UB! (Precondition violation) But why does emplace_back compile when push_back doesn t? Slide 23 Direct vs. Copy Initialization Direct initialization may call explicit constructors. Copy initialization can t. 8.5/15-16 How know which used where? Memorize :-( std::regex r1(nullptr); std::regex r2{nullptr}; std::regex r3 = nullptr; // compiles! Direct initialization // may call explicit ctor // ditto // error! Copy initialization // can't call explicit ctor Slide 24
Direct vs. Copy Initialization Emplacement functions use direct initialization: regexes.emplace_back(nullptr); Insertion functions use copy initialization: regexes.push_back(nullptr); // compiles! // error! Slide 25 Emplacement less safe than insertion. May invoke explicit constructors. One More Conclusion Slide 26
Performance: Summary Emplacement can reduce number of constructions/destructions. In theory, emplacement never costs more than insertion. In practice, emplacement often does. Emplacement most likely a win when: Value being added is constructed into the container, not assigned. Argument(s) passed are different from T (for Container<T>). Value to be added unlikely to be rejected as a duplicate. Safety: Insertion respects explicit constructors, emplacement doesn t. Slide 27 Guideline Prefer emplacement to insertion. Many thanks to: Stephan T. Lavavej Howard Hinnant Michael Winterberg Slide 28
Intermission Promulgation Promulgation Promulgation Promulgation Promulgation Promulgation Promulgation Promulgation
Promulgating the Message 1991: Writing Presentations 2014: Writing Presentations Video Image: Loudspeakers, Pelle Sten @ flickr Slide 31 Black ink on white, fixed-size pages. The Writing Landscape: 1991 Slide 32
Flashback to my TOC 2009 talk: The Writing Landscape: 2014 Slide 33
Authoring Challenges in a Multiplatform World The Vision and Why Authors Matter What's in here Printed book Computer screen Portable electronic book reader Manuscript from author Multipurpose portable device affects how easy and effective these transitions are Audio device Copyrighted material, all rights reserved. Slide 3 The Goal Platform-agnostic manuscript from author. Facilitates: Exploitation of platforms' strengths and capabilities. Accommodation of their weaknesses. Copyrighted material, all rights reserved. Slide 4 Copyrighted material, all rights reserved.
Authoring Challenges in a Multiplatform World Some Platform Variations Color? Display Size Diagrams, Graphs, Tables? Page- Based? Dynamic? Personalizable? Rarely Medium Yes Yes No Typically Big Yes Maybe Yes Maybe Medium Maybe Maybe Yes Maybe with POD In concept In concept Typically Small Yes, but small Maybe Yes In concept Maybe Typically small Maybe No Rarely In concept Copyrighted material, all rights reserved. Slide 5 What Works Poorly Conventional manuscript from author Authors design/write books that are: Static Monochrome Page-based Visible Other formats suffer. Copyrighted material, all rights reserved. Slide 6 Copyrighted material, all rights reserved.
Authoring Challenges in a Multiplatform World What may go in a Platform-Agnostic Manuscript? Anything that works in printed form. The usual suspects: Text, diagrams, tables, photographs, etc. In addition: Color Video/Animations Audio Copyrighted material, all rights reserved. Slide 7 Challenge: Adopting New Tools New expository tools: Color, video/animations, audio Authors need to learn: What works where? Why? What doesn t? Why not? As true for novelists as for technical writers. Copyrighted material, all rights reserved. Slide 8 Copyrighted material, all rights reserved.
Regarding Color... Legitimate uses (IMO): Code highlighting. Syntax coloring. Diagrams and tables. Visual appeal. Slide 34 Not Everybody Gets It Slide 35
The Line Length Problem 64 Slide 36 The Solution? Slide 37
The Animation Approach E.g., in Sean Parent s C++ Seasoning at GoingNative 2013: Slide 43
The Animation Approach E.g., in Sean Parent s C++ Seasoning at GoingNative 2013: Slide 44 The Animation Approach E.g., in Sean Parent s C++ Seasoning at GoingNative 2013: Slide 45
The Animation Approach E.g., in Sean Parent s C++ Seasoning at GoingNative 2013: Slide 46 The Animation Approach Advantages: Good for live, remote, and asynchronous audiences. Disadvantages: Lots of up-front work. Lots. Inflexible. Slide 47
The Solution? Touch-based laser pointer and annotation support? Paul Wagner on using ipad/doceri in the Classroom Slide 48 Take-Aways Base guidelines on thorough analysis and solid technical arguments. Write for modern digital devices. Design live presentations to be recorded.
Further Information Automatic Detection of Programming Errors: Initial Thoughts on a lint++, Scott Meyers and Moises Lejter, Proceedings of the 1991 USENIX C++ Conference, April 1991. Effective Effective Books, Scott Meyers, The View From Aristeia, 23 January 2013. insert vs. emplace, Howard Hinnant, 28 July 2014, http://tinyurl.com/lxf67ky. Effective Modern C++, Scott Meyers, O Reilly, 2015. Authoring Challenges in a Multiplatform World, Scott Meyers, Tools of Change, February 2009. The Line-Length Problem, Scott Meyers, The View from Aristeia, 13 March 2013. clang-format: Automatic formatting for C++, Daniel Jasper, 2013 European LLVM Conference, 29 April 2013. C++ Seasoning, Sean Parent, GoingNative 2013, 4 September 2013. Paul Wagner on using ipad/doceri in the Classroom, YouTube, 22 November 2011. Slide 50 Use discount code AUTHD at oreilly.com for 40%-50% off!
Licensing Information Scott Meyers licenses materials for this and other training courses for commercial or personal use. Details: Commercial use: http://aristeia.com/licensing/licensing.html Personal use: http://aristeia.com/licensing/personaluse.html Courses currently available for personal use include: Slide 52 About Scott Meyers Scott Meyers is one of the world s foremost authorities on C++. His web site, http://aristeia.com/ provides information on: Technical training services Upcoming presentations Books, articles, online videos, etc. Professional activities blog Slide 53