C++核心指导原则: 函数部分

C++ Core Guidelines 整理目录

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

Function definition rules

F.1: “Package” meaningful operations as carefully named functions

F.2: A function should perform a single logical operation

F.3: Keep functions short and simple

F.4: If a function might have to be evaluated at compile time, declare it constexpr

F.5: If a function is very small and time-critical, declare it inline

F.6: If your function must not throw, declare it noexcept

F.7: For general use, take T* or T& arguments rather than smart pointers

F.8: Prefer pure functions

F.9: Unused parameters should be unnamed

F.10: If an operation can be reused, give it a name

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

Parameter passing expression rules

F.15: Prefer simple and conventional ways of passing information

F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const

F.17: For “in-out” parameters, pass by reference to non-const

F.18: For “will-move-from” parameters, pass by X&& and std::move the parameter

F.19: For “forward” parameters, pass by TP&& and only std::forward the parameter

F.20: For “out” output values, prefer return values to output parameters

F.21: To return multiple “out” values, prefer returning a struct

F.60: Prefer T* over T& when “no argument” is a valid option

Parameter passing semantic rules

F.22: Use T* or owner<T*> to designate a single object

F.23: Use a not_null<T> to indicate that “null” is not a valid value

F.24: Use a span<T> or a span_p<T> to designate a half-open sequence

F.25: Use a zstring or a not_null<zstring> to designate a C-style string

F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed

F.27: Use a shared_ptr<T> to share ownership

Value return semantic rules

F.42: Return a T* to indicate a position (only)

F.43: Never (directly or indirectly) return a pointer or a reference to a local object

F.44: Return a T& when copy is undesirable and “returning no object” isn’t needed

F.45: Don’t return a T&&

F.46: int is the return type for main()

F.47: Return T& from assignment operators

F.48: Don’t return std::move(local)

F.49: Don’t return const T

Other function rules

F.50: Use a lambda when a function won’t do (to capture local variables, or to write a local function)

F.51: Where there is a choice, prefer default arguments over overloading

F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms

F.53: Avoid capturing by reference in lambdas that will be used non-locally, including returned, stored on the heap, or passed to another thread

F.54: When writing a lambda that captures this or any class data member, don’t use [=] default capture

F.55: Don’t use va_arg arguments

F.56: Avoid unnecessary condition nesting