C++核心指导原则: 泛型编程

C++ Core Guidelines 整理目录

  1. 哲学部分
  2. 接口(Interface)部分
  3. 函数部分
  4. 类和类层次结构部分
  5. 枚举部分
  6. 资源管理部分
  7. 表达式和语句部分
  8. 性能部分
  9. 并发和并行
  10. 错误处理
  11. 常量和不可变性
  12. 泛型编程
  13. 源文件
  14. 命名和布局建议
  15. 标准库
  16. 其他规则

模板规则

模板使用规则

T.1: Use templates to raise the level of abstraction of code

T.2: Use templates to express algorithms that apply to many argument types

T.3: Use templates to express containers and ranges

T.4: Use templates to express syntax tree manipulation

T.5: Combine generic and OO techniques to amplify their strengths, not their costs

概念(Concept)使用规则

T.10: Specify concepts for all template arguments

T.11: Whenever possible use standard concepts

T.12: Prefer concept names over auto for local variables

T.13: Prefer the shorthand notation for simple, single-type argument concepts

概念(Concept)定义规则

T.20: Avoid “concepts” without meaningful semantics

T.21: Require a complete set of operations for a concept

T.22: Specify axioms for concepts

T.23: Differentiate a refined concept from its more general case by adding new use patterns

T.24: Use tag classes or traits to differentiate concepts that differ only in semantics

T.25: Avoid complementary constraints

T.26: Prefer to define concepts in terms of use-patterns rather than simple syntax

T.30: Use concept negation (!C<T>) sparingly to express a minor difference

T.31: Use concept disjunction (C1<T> || C2<T>) sparingly to express alternatives

模板接口规则

T.40: Use function objects to pass operations to algorithms

T.41: Require only essential properties in a template’s concepts

T.42: Use template aliases to simplify notation and hide implementation details

T.43: Prefer using over typedef for defining aliases

T.44: Use function templates to deduce class template argument types (where feasible)

T.46: Require template arguments to be at least semiregular

T.47: Avoid highly visible unconstrained templates with common names

T.48: If your compiler does not support concepts, fake them with enable_if

T.49: Where possible, avoid type-erasure

模板定义规则

T.60: Minimize a template’s context dependencies

T.61: Do not over-parameterize members (SCARY)

T.62: Place non-dependent class template members in a non-templated base class

T.64: Use specialization to provide alternative implementations of class templates

T.65: Use tag dispatch to provide alternative implementations of functions

T.67: Use specialization to provide alternative implementations for irregular types

T.68: Use {} rather than () within templates to avoid ambiguities

T.69: Inside a template, don’t make an unqualified non-member function call unless you intend it to be a customization point

模板与层次结构规则

T.80: Do not naively templatize a class hierarchy

T.81: Do not mix hierarchies and arrays

T.82: Linearize a hierarchy when virtual functions are undesirable

T.83: Do not declare a member function template virtual

T.84: Use a non-template core implementation to provide an ABI-stable interface

可变参数模板规则

T.100: Use variadic templates when you need a function that takes a variable number of arguments of a variety of types

T.101: ??? How to pass arguments to a variadic template ???

T.102: ??? How to process arguments to a variadic template ???

T.103: Don’t use variadic templates for homogeneous argument lists

元编程规则

T.120: Use template metaprogramming only when you really need to

T.121: Use template metaprogramming primarily to emulate concepts

T.122: Use templates (usually template aliases) to compute types at compile time

T.123: Use constexpr functions to compute values at compile time

T.124: Prefer to use standard-library TMP facilities

T.125: If you need to go beyond the standard-library TMP facilities, use an existing library

其他模板规则

T.140: If an operation can be reused, give it a name

T.141: Use an unnamed lambda if you need a simple function object in one place only

T.142: Use template variables to simplify notation

T.143: Don’t write unintentionally non-generic code

T.144: Don’t specialize function templates

T.150: Check that a class matches a concept using static_assert