24 April 2022

C++ 核心指南目录

理由

“不寻常的、聪明的”技巧会让其他程序员吃惊、难以理解、容易出bug。如果确实觉得不走寻常路是代码优化的需要,请进行测试,是否提升性能,并用文档和注释解释原因。

以下表格总结了 F.16-21 的建议。

常规传参表:

  复制成本低[1] 移动成本低/适中[2] 移动成本高[3]
出参 X f() X f() f(X&)
出参/入参 f(X&) f(X&) f(X&)
入参 f(X) f(const X&) f(const X&)
入参,保留副本 f(X) f(const X&) f(const X&)

高级传参表:

  复制成本低[1] 移动成本低/适中[2] 移动成本高[3]
出参 X f() X f() f(X&)
出参/入参 f(X&) f(X&) f(X&)
入参 f(X) f(const X&) f(const X&)
入参,保留副本 f(X) f(const X&) + f(X&&) & move f(const X&)
入参,移入 f(X&&) f(X&&) f(X&&)

其中:

  • [1]
    • 复制成本低
    • 无法复制(如 int, unique_ptr
  • [2]
    • 移动成本低(如 vector<T>, string
    • 移动成本适中(如 array<vector>, BigPOD
    • 未知(如:未知类型,模板)
  • [3]
    • 移动成本高(如 BigPOD[], array<BigPOD>

只有证明是必需的时候,才使用高级技巧,并添加文档或代码注释。

【注】 && 是 C++11 标准定义的新的引用操作符:右值引用 (rvalue reference)。 int&& a 表示 a 是一个右值(r-value)引用。一般用于声明函数的参数。简单来说:右值没有内存地址,如数字 6 或字符 ’v’。 int aa 是一个左值(l-value)。不过 a+2 是一个右值。