24 April 2022

C++ 核心指南目录

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

理由

“不同寻常的奇技淫巧”会让其他程序员感到吃惊、难以理解、并且代码容易出 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是一个右值。