O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

C++ Templates: The Complete Guide, 2nd Edition

Book Description

Templates are among the most powerful features of C++, but they remain misunderstood and underutilized, even as the C++ language and development community have advanced. In C++ Templates, Second Edition, three pioneering C++ experts show why, when, and how to use modern templates to build software that’s cleaner, faster, more efficient, and easier to maintain.

Now extensively updated for the C++11, C++14, and C++17 standards, this new edition presents state-of-the-art techniques for a wider spectrum of applications. The authors provide authoritative explanations of all new language features that either improve templates or interact with them, including variadic templates, generic lambdas, class template argument deduction, compile-time if, forwarding references, and user-defined literals. They also deeply delve into fundamental language concepts (like value categories) and fully cover all standard type traits.

The book starts with an insightful tutorial on basic concepts and relevant language features. The remainder of the book serves as a comprehensive reference, focusing first on language details and then on coding techniques, advanced applications, and sophisticated idioms. Throughout, examples clearly illustrate abstract concepts and demonstrate best practices for exploiting all that C++ templates can do.

  • Understand exactly how templates behave, and avoid common pitfalls
  • Use templates to write more efficient, flexible, and maintainable software
  • Master today’s most effective idioms and techniques
  • Reuse source code without compromising performance or safety
  • Benefit from utilities for generic programming in the C++ Standard Library
  • Preview the upcoming concepts feature

The companion website, tmplbook.com, contains sample code and additional updates.

Table of Contents

  1. Cover Page
  2. Title Page
  3. Copyright Page
  4. Dedication
  5. Contents
  6. Preface
  7. Acknowledgments for the Second Edition
  8. Acknowledgments for the First Edition
  9. About This Book
    1. What You Should Know Before Reading This Book
    2. Overall Structure of the Book
    3. How to Read This Book
    4. Some Remarks About Programming Style
    5. The C++11, C++14, and C++17 Standards
    6. Example Code and Additional Information
    7. Feedback
  10. Part I: The Basics
    1. 1 Function Templates
      1. 1.1 A First Look at Function Templates
        1. 1.1.1 Defining the Template
        2. 1.1.2 Using the Template
        3. 1.1.3 Two-Phase Translation
      2. 1.2 Template Argument Deduction
      3. 1.3 Multiple Template Parameters
        1. 1.3.1 Template Parameters for Return Types
        2. 1.3.2 Deducing the Return Type
        3. 1.3.3 Return Type as Common Type
      4. 1.4 Default Template Arguments
      5. 1.5 Overloading Function Templates
      6. 1.6 But, Shouldn’t We …?
        1. 1.6.1 Pass by Value or by Reference?
        2. 1.6.2 Why Not inline?
        3. 1.6.3 Why Not constexpr?
      7. 1.7 Summary
    2. 2 Class Templates
      1. 2.1 Implementation of Class Template Stack
        1. 2.1.1 Declaration of Class Templates
        2. 2.1.2 Implementation of Member Functions
      2. 2.2 Use of Class Template Stack
      3. 2.3 Partial Usage of Class Templates
        1. 2.3.1 Concepts
      4. 2.4 Friends
      5. 2.5 Specializations of Class Templates
      6. 2.6 Partial Specialization
      7. 2.7 Default Class Template Arguments
      8. 2.8 Type Aliases
      9. 2.9 Class Template Argument Deduction
      10. 2.10 Templatized Aggregates
      11. 2.11 Summary
    3. 3 Nontype Template Parameters
      1. 3.1 Nontype Class Template Parameters
      2. 3.2 Nontype Function Template Parameters
      3. 3.3 Restrictions for Nontype Template Parameters
      4. 3.4 Template Parameter Type auto
      5. 3.5 Summary
    4. 4 Variadic Templates
      1. 4.1 Variadic Templates
        1. 4.1.1 Variadic Templates by Example
        2. 4.1.2 Overloading Variadic and Nonvariadic Templates
        3. 4.1.3 Operator sizeof…
      2. 4.2 Fold Expressions
      3. 4.3 Application of Variadic Templates
      4. 4.4 Variadic Class Templates and Variadic Expressions
        1. 4.4.1 Variadic Expressions
        2. 4.4.2 Variadic Indices
        3. 4.4.3 Variadic Class Templates
        4. 4.4.4 Variadic Deduction Guides
        5. 4.4.5 Variadic Base Classes and using
      5. 4.5 Summary
    5. 5 Tricky Basics
      1. 5.1 Keyword typename
      2. 5.2 Zero Initialization
      3. 5.3 Using this->
      4. 5.4 Templates for Raw Arrays and String Literals
      5. 5.5 Member Templates
        1. 5.5.1 The .template Construct
        2. 5.5.2 Generic Lambdas and Member Templates
      6. 5.6 Variable Templates
      7. 5.7 Template Template Parameters
      8. 5.8 Summary
    6. 6 Move Semantics and enable_if<>
      1. 6.1 Perfect Forwarding
      2. 6.2 Special Member Function Templates
      3. 6.3 Disable Templates with enable_if<>
      4. 6.4 Using enable_if<>
      5. 6.5 Using Concepts to Simplify enable_if<> Expressions
      6. 6.6 Summary
    7. 7 By Value or by Reference?
      1. 7.1 Passing by Value
      2. 7.2 Passing by Reference
        1. 7.2.1 Passing by Constant Reference
        2. 7.2.2 Passing by Nonconstant Reference
        3. 7.2.3 Passing by Forwarding Reference
      3. 7.3 Using std::ref() and std::cref()
      4. 7.4 Dealing with String Literals and Raw Arrays
        1. 7.4.1 Special Implementations for String Literals and Raw Arrays
      5. 7.5 Dealing with Return Values
      6. 7.6 Recommended Template Parameter Declarations
      7. 7.7 Summary
    8. 8 Compile-Time Programming
      1. 8.1 Template Metaprogramming
      2. 8.2 Computing with constexpr
      3. 8.3 Execution Path Selection with Partial Specialization
      4. 8.4 SFINAE (Substitution Failure Is Not An Error)
        1. 8.4.1 Expression SFINAE with decltype
      5. 8.5 Compile-Time if
      6. 8.6 Summary
    9. 9 Using Templates in Practice
      1. 9.1 The Inclusion Model
        1. 9.1.1 Linker Errors
        2. 9.1.2 Templates in Header Files
      2. 9.2 Templates and inline
      3. 9.3 Precompiled Headers
      4. 9.4 Decoding the Error Novel
      5. 9.5 Afternotes
      6. 9.6 Summary
    10. 10 Basic Template Terminology
      1. 10.1 “Class Template” or “Template Class”?
      2. 10.2 Substitution, Instantiation, and Specialization
      3. 10.3 Declarations versus Definitions
        1. 10.3.1 Complete versus Incomplete Types
      4. 10.4 The One-Definition Rule
      5. 10.5 Template Arguments versus Template Parameters
      6. 10.6 Summary
    11. 11 Generic Libraries
      1. 11.1 Callables
        1. 11.1.1 Supporting Function Objects
        2. 11.1.2 Dealing with Member Functions and Additional Arguments
        3. 11.1.3 Wrapping Function Calls
      2. 11.2 Other Utilities to Implement Generic Libraries
        1. 11.2.1 Type Traits
        2. 11.2.2 std::addressof()
        3. 11.2.3 std::declval()
      3. 11.3 Perfect Forwarding Temporaries
      4. 11.4 References as Template Parameters
      5. 11.5 Defer Evaluations
      6. 11.6 Things to Consider When Writing Generic Libraries
      7. 11.7 Summary
  11. Part II: Templates in Depth
    1. 12 Fundamentals in Depth
      1. 12.1 Parameterized Declarations
        1. 12.1.1 Virtual Member Functions
        2. 12.1.2 Linkage of Templates
        3. 12.1.3 Primary Templates
      2. 12.2 Template Parameters
        1. 12.2.1 Type Parameters
        2. 12.2.2 Nontype Parameters
        3. 12.2.3 Template Template Parameters
        4. 12.2.4 Template Parameter Packs
        5. 12.2.5 Default Template Arguments
      3. 12.3 Template Arguments
        1. 12.3.1 Function Template Arguments
        2. 12.3.2 Type Arguments
        3. 12.3.3 Nontype Arguments
        4. 12.3.4 Template Template Arguments
        5. 12.3.5 Equivalence
      4. 12.4 Variadic Templates
        1. 12.4.1 Pack Expansions
        2. 12.4.2 Where Can Pack Expansions Occur?
        3. 12.4.3 Function Parameter Packs
        4. 12.4.4 Multiple and Nested Pack Expansions
        5. 12.4.5 Zero-Length Pack Expansions
        6. 12.4.6 Fold Expressions
      5. 12.5 Friends
        1. 12.5.1 Friend Classes of Class Templates
        2. 12.5.2 Friend Functions of Class Templates
        3. 12.5.3 Friend Templates
      6. 12.6 Afternotes
    2. 13 Names in Templates
      1. 13.1 Name Taxonomy
      2. 13.2 Looking Up Names
        1. 13.2.1 Argument-Dependent Lookup
        2. 13.2.2 Argument-Dependent Lookup of Friend Declarations
        3. 13.2.3 Injected Class Names
        4. 13.2.4 Current Instantiations
      3. 13.3 Parsing Templates
        1. 13.3.1 Context Sensitivity in Nontemplates
        2. 13.3.2 Dependent Names of Types
        3. 13.3.3 Dependent Names of Templates
        4. 13.3.4 Dependent Names in Using Declarations
        5. 13.3.5 ADL and Explicit Template Arguments
        6. 13.3.6 Dependent Expressions
        7. 13.3.7 Compiler Errors
      4. 13.4 Inheritance and Class Templates
        1. 13.4.1 Nondependent Base Classes
        2. 13.4.2 Dependent Base Classes
      5. 13.5 Afternotes
    3. 14 Instantiation
      1. 14.1 On-Demand Instantiation
      2. 14.2 Lazy Instantiation
        1. 14.2.1 Partial and Full Instantiation
        2. 14.2.2 Instantiated Components
      3. 14.3 The C++ Instantiation Model
        1. 14.3.1 Two-Phase Lookup
        2. 14.3.2 Points of Instantiation
        3. 14.3.3 The Inclusion Model
      4. 14.4 Implementation Schemes
        1. 14.4.1 Greedy Instantiation
        2. 14.4.2 Queried Instantiation
        3. 14.4.3 Iterated Instantiation
      5. 14.5 Explicit Instantiation
        1. 14.5.1 Manual Instantiation
        2. 14.5.2 Explicit Instantiation Declarations
      6. 14.6 Compile-Time if Statements
      7. 14.7 In the Standard Library
      8. 14.8 Afternotes
    4. 15 Template Argument Deduction
      1. 15.1 The Deduction Process
      2. 15.2 Deduced Contexts
      3. 15.3 Special Deduction Situations
      4. 15.4 Initializer Lists
      5. 15.5 Parameter Packs
        1. 15.5.1 Literal Operator Templates
      6. 15.6 Rvalue References
        1. 15.6.1 Reference Collapsing Rules
        2. 15.6.2 Forwarding References
        3. 15.6.3 Perfect Forwarding
        4. 15.6.4 Deduction Surprises
      7. 15.7 SFINAE (Substitution Failure Is Not An Error)
        1. 15.7.1 Immediate Context
      8. 15.8 Limitations of Deduction
        1. 15.8.1 Allowable Argument Conversions
        2. 15.8.2 Class Template Arguments
        3. 15.8.3 Default Call Arguments
        4. 15.8.4 Exception Specifications
      9. 15.9 Explicit Function Template Arguments
      10. 15.10 Deduction from Initializers and Expressions
        1. 15.10.1 The auto Type Specifier
        2. 15.10.2 Expressing the Type of an Expression with decltype
        3. 15.10.3 decltype(auto)
        4. 15.10.4 Special Situations for auto Deduction
        5. 15.10.5 Structured Bindings
        6. 15.10.6 Generic Lambdas
      11. 15.11 Alias Templates
      12. 15.12 Class Template Argument Deduction
        1. 15.12.1 Deduction Guides
        2. 15.12.2 Implicit Deduction Guides
        3. 15.12.3 Other Subtleties
      13. 15.13 Afternotes
    5. 16 Specialization and Overloading
      1. 16.1 When “Generic Code” Doesn’t Quite Cut It
        1. 16.1.1 Transparent Customization
        2. 16.1.2 Semantic Transparency
      2. 16.2 Overloading Function Templates
        1. 16.2.1 Signatures
        2. 16.2.2 Partial Ordering of Overloaded Function Templates
        3. 16.2.3 Formal Ordering Rules
        4. 16.2.4 Templates and Nontemplates
        5. 16.2.5 Variadic Function Templates
      3. 16.3 Explicit Specialization
        1. 16.3.1 Full Class Template Specialization
        2. 16.3.2 Full Function Template Specialization
        3. 16.3.3 Full Variable Template Specialization
        4. 16.3.4 Full Member Specialization
      4. 16.4 Partial Class Template Specialization
      5. 16.5 Partial Variable Template Specialization
      6. 16.6 Afternotes
    6. 17 Future Directions
      1. 17.1 Relaxed typename Rules
      2. 17.2 Generalized Nontype Template Parameters
      3. 17.3 Partial Specialization of Function Templates
      4. 17.4 Named Template Arguments
      5. 17.5 Overloaded Class Templates
      6. 17.6 Deduction for Nonfinal Pack Expansions
      7. 17.7 Regularization of void
      8. 17.8 Type Checking for Templates
      9. 17.9 Reflective Metaprogramming
      10. 17.10 Pack Facilities
      11. 17.11 Modules
  12. Part III: Templates and Design
    1. 18 The Polymorphic Power of Templates
      1. 18.1 Dynamic Polymorphism
      2. 18.2 Static Polymorphism
      3. 18.3 Dynamic versus Static Polymorphism
      4. 18.4 Using Concepts
      5. 18.5 New Forms of Design Patterns
      6. 18.6 Generic Programming
      7. 18.7 Afternotes
    2. 19 Implementing Traits
      1. 19.1 An Example: Accumulating a Sequence
        1. 19.1.1 Fixed Traits
        2. 19.1.2 Value Traits
        3. 19.1.3 Parameterized Traits
      2. 19.2 Traits versus Policies and Policy Classes
        1. 19.2.1 Traits and Policies: What’s the Difference?
        2. 19.2.2 Member Templates versus Template Template Parameters
        3. 19.2.3 Combining Multiple Policies and/or Traits
        4. 19.2.4 Accumulation with General Iterators
      3. 19.3 Type Functions
        1. 19.3.1 Element Types
        2. 19.3.2 Transformation Traits
        3. 19.3.3 Predicate Traits
        4. 19.3.4 Result Type Traits
      4. 19.4 SFINAE-Based Traits
        1. 19.4.1 SFINAE Out Function Overloads
        2. 19.4.2 SFINAE Out Partial Specializations
        3. 19.4.3 Using Generic Lambdas for SFINAE
        4. 19.4.4 SFINAE-Friendly Traits
      5. 19.5 IsConvertibleT
      6. 19.6 Detecting Members
        1. 19.6.1 Detecting Member Types
        2. 19.6.2 Detecting Arbitrary Member Types
        3. 19.6.3 Detecting Nontype Members
        4. 19.6.4 Using Generic Lambdas to Detect Members
      7. 19.7 Other Traits Techniques
        1. 19.7.1 If-Then-Else
        2. 19.7.2 Detecting Nonthrowing Operations
        3. 19.7.3 Traits Convenience
      8. 19.8 Type Classification
        1. 19.8.1 Determining Fundamental Types
        2. 19.8.2 Determining Compound Types
        3. 19.8.3 Identifying Function Types
        4. 19.8.4 Determining Class Types
        5. 19.8.5 Determining Enumeration Types
      9. 19.9 Policy Traits
        1. 19.9.1 Read-Only Parameter Types
      10. 19.10 In the Standard Library
      11. 19.11 Afternotes
    3. 20 Overloading on Type Properties
      1. 20.1 Algorithm Specialization
      2. 20.2 Tag Dispatching
      3. 20.3 Enabling/Disabling Function Templates
        1. 20.3.1 Providing Multiple Specializations
        2. 20.3.2 Where Does the EnableIf Go?
        3. 20.3.3 Compile-Time if
        4. 20.3.4 Concepts
      4. 20.4 Class Specialization
        1. 20.4.1 Enabling/Disabling Class Templates
        2. 20.4.2 Tag Dispatching for Class Templates
      5. 20.5 Instantiation-Safe Templates
      6. 20.6 In the Standard Library
      7. 20.7 Afternotes
    4. 21 Templates and Inheritance
      1. 21.1 The Empty Base Class Optimization (EBCO)
        1. 21.1.1 Layout Principles
        2. 21.1.2 Members as Base Classes
      2. 21.2 The Curiously Recurring Template Pattern (CRTP)
        1. 21.2.1 The Barton-Nackman Trick
        2. 21.2.2 Operator Implementations
        3. 21.2.3 Facades
      3. 21.3 Mixins
        1. 21.3.1 Curious Mixins
        2. 21.3.2 Parameterized Virtuality
      4. 21.4 Named Template Arguments
      5. 21.5 Afternotes
    5. 22 Bridging Static and Dynamic Polymorphism
      1. 22.1 Function Objects, Pointers, and std::function<>
      2. 22.2 Generalized Function Pointers
      3. 22.3 Bridge Interface
      4. 22.4 Type Erasure
      5. 22.5 Optional Bridging
      6. 22.6 Performance Considerations
      7. 22.7 Afternotes
    6. 23 Metaprogramming
      1. 23.1 The State of Modern C++ Metaprogramming
        1. 23.1.1 Value Metaprogramming
        2. 23.1.2 Type Metaprogramming
        3. 23.1.3 Hybrid Metaprogramming
        4. 23.1.4 Hybrid Metaprogramming for Unit Types
      2. 23.2 The Dimensions of Reflective Metaprogramming
      3. 23.3 The Cost of Recursive Instantiation
        1. 23.3.1 Tracking All Instantiations
      4. 23.4 Computational Completeness
      5. 23.5 Recursive Instantiation versus Recursive Template Arguments
      6. 23.6 Enumeration Values versus Static Constants
      7. 23.7 Afternotes
    7. 24 Typelists
      1. 24.1 Anatomy of a Typelist
      2. 24.2 Typelist Algorithms
        1. 24.2.1 Indexing
        2. 24.2.2 Finding the Best Match
        3. 24.2.3 Appending to a Typelist
        4. 24.2.4 Reversing a Typelist
        5. 24.2.5 Transforming a Typelist
        6. 24.2.6 Accumulating Typelists
        7. 24.2.7 Insertion Sort
      3. 24.3 Nontype Typelists
        1. 24.3.1 Deducible Nontype Parameters
      4. 24.4 Optimizing Algorithms with Pack Expansions
      5. 24.5 Cons-style Typelists
      6. 24.6 Afternotes
    8. 25 Tuples
      1. 25.1 Basic Tuple Design
        1. 25.1.1 Storage
        2. 25.1.2 Construction
      2. 25.2 Basic Tuple Operations
        1. 25.2.1 Comparison
        2. 25.2.2 Output
      3. 25.3 Tuple Algorithms
        1. 25.3.1 Tuples as Typelists
        2. 25.3.2 Adding to and Removing from a Tuple
        3. 25.3.3 Reversing a Tuple
        4. 25.3.4 Index Lists
        5. 25.3.5 Reversal with Index Lists
        6. 25.3.6 Shuffle and Select
      4. 25.4 Expanding Tuples
      5. 25.5 Optimizing Tuple
        1. 25.5.1 Tuples and the EBCO
        2. 25.5.2 Constant-time get()
      6. 25.6 Tuple Subscript
      7. 25.7 Afternotes
    9. 26 Discriminated Unions
      1. 26.1 Storage
      2. 26.2 Design
      3. 26.3 Value Query and Extraction
      4. 26.4 Element Initialization, Assignment and Destruction
        1. 26.4.1 Initialization
        2. 26.4.2 Destruction
        3. 26.4.3 Assignment
      5. 26.5 Visitors
        1. 26.5.1 Visit Result Type
        2. 26.5.2 Common Result Type
      6. 26.6 Variant Initialization and Assignment
      7. 26.7 Afternotes
    10. 27 Expression Templates
      1. 27.1 Temporaries and Split Loops
      2. 27.2 Encoding Expressions in Template Arguments
        1. 27.2.1 Operands of the Expression Templates
        2. 27.2.2 The Array Type
        3. 27.2.3 The Operators
        4. 27.2.4 Review
        5. 27.2.5 Expression Templates Assignments
      3. 27.3 Performance and Limitations of Expression Templates
      4. 27.4 Afternotes
    11. 28 Debugging Templates
      1. 28.1 Shallow Instantiation
      2. 28.2 Static Assertions
      3. 28.3 Archetypes
      4. 28.4 Tracers
      5. 28.5 Oracles
      6. 28.6 Afternotes
  13. Appendixes
    1. A The One-Definition Rule
      1. A.1 Translation Units
      2. A.2 Declarations and Definitions
      3. A.3 The One-Definition Rule in Detail
        1. A.3.1 One-per-Program Constraints
        2. A.3.2 One-per-Translation Unit Constraints
        3. A.3.3 Cross-Translation Unit Equivalence Constraints
    2. B Value Categories
      1. B.1 Traditional Lvalues and Rvalues
        1. B.1.1 Lvalue-to-Rvalue Conversions
      2. B.2 Value Categories Since C++11
        1. B.2.1 Temporary Materialization
      3. B.3 Checking Value Categories with decltype
      4. B.4 Reference Types
    3. C Overload Resolution
      1. C.1 When Does Overload Resolution Kick In?
      2. C.2 Simplified Overload Resolution
        1. C.2.1 The Implied Argument for Member Functions
        2. C.2.2 Refining the Perfect Match
      3. C.3 Overloading Details
        1. C.3.1 Prefer Nontemplates or More Specialized Templates
        2. C.3.2 Conversion Sequences
        3. C.3.3 Pointer Conversions
        4. C.3.4 Initializer Lists
        5. C.3.5 Functors and Surrogate Functions
        6. C.3.6 Other Overloading Contexts
    4. D Standard Type Utilities
      1. D.1 Using Type Traits
        1. D.1.1 std::integral_constant and std::bool_constant
        2. D.1.2 Things You Should Know When Using Traits
      2. D.2 Primary and Composite Type Categories
        1. D.2.1 Testing for the Primary Type Category
        2. D.2.2 Test for Composite Type Categories
      3. D.3 Type Properties and Operations
        1. D.3.1 Other Type Properties
        2. D.3.2 Test for Specific Operations
      4. D.3.3 Relationships Between Types
      5. D.4 Type Construction
      6. D.5 Other Traits
      7. D.6 Combining Type Traits
      8. D.7 Other Utilities
    5. E Concepts
      1. E.1 Using Concepts
      2. E.2 Defining Concepts
      3. E.3 Overloading on Constraints
        1. E.3.1 Constraint Subsumption
        2. E.3.2 Constraints and Tag Dispatching
      4. E.4 Concept Tips
        1. E.4.1 Testing Concepts
        2. E.4.2 Concept Granularity
        3. E.4.3 Binary Compatibility
  14. Bibliography
    1. Forums
    2. Books and Web Sites
  15. Glossary
  16. Index