专栏首页C++核心准则原文翻译C++核心准则编译边学-F.20 输出结果时更应该使用返回值而不是输出参数

C++核心准则编译边学-F.20 输出结果时更应该使用返回值而不是输出参数

F.20: For "out" output values, prefer return values to output parameters(输出结果时更应该使用返回值而不是输出参数)

Reason(原因)

A return value is self-documenting, whereas a & could be either in-out or out-only and is liable to be misused.

返回值本身可以说明用途,而引用类型可以是输入/输出参数也有可能只是输出参数,容易被误用。

This includes large objects like standard containers that use implicit move operations for performance and to avoid explicit memory management.

这种观点可以覆盖像标准容器那样的大对象,它们会为了性能和避免显式内存管理而使用隐式移动操作。

If you have multiple values to return, use a tuple or similar multi-member type.

如果你有多个值需要返回,使用tuple或者类似的多成员类型。

译者注:tuple可以参考以下文章。

https://mp.weixin.qq.com/s/kQEYhjpfE9XYBiRgp_fJSw

Example(示例)

// OK: return pointers to elements with the value x
vector<const int*> find_all(const vector<int>&, int x);

// Bad: place pointers to elements with value x in-out
void find_all(const vector<int>&, vector<const int*>& out, int x);

Note(注意)

A struct of many (individually cheap-to-move) elements may be in aggregate expensive to move.

包含多个(单独看都可以低成本移动)元素的结构体合起来移动时可能会代价高昂。

It is not recommended to return a const value. Such older advice is now obsolete; it does not add value, and it interferes with move semantics.

不推荐返回常量值。这种过时的建议现在已经被淘汰;它不会带来好处,而且其接口含有移动语义。

const vector<int> fct();    // bad: that "const" is more trouble than it is worth

vector<int> g(const vector<int>& vx)
{
    // ...
    fct() = vx;   // prevented by the "const"
    // ...
    return fct(); // expensive copy: move semantics suppressed by the "const"
}

The argument for adding const to a return value is that it prevents (very rare) accidental access to a temporary. The argument against is prevents (very frequent) use of move semantics.

建议为返回值增加const修饰的观点认为,这样会阻止(极少发生的)对临时变量的意外访问。相反的观点认为这样做会(非常多地)阻止移动语义的运用。

Exceptions(例外)
  • For non-value types, such as types in an inheritance hierarchy, return the object by unique_ptr or shared_ptr. 对于非值类型函数,例如处于继承关系中的类型,通过unique_ptr或者shared_ptr返回对象。 译者注:两种方式都可以避免不必要的拷贝动作。
  • If a type is expensive to move (e.g., array<BigPOD>), consider allocating it on the free store and return a handle (e.g., unique_ptr), or passing it in a reference to non-const target object to fill (to be used as an out-parameter). 如果某种类型(例如array<BigPOD>)的移动成本很高,考虑从自由存储上为其申请内存并使用句柄(例如unique_prt)返回它,或者通过用于填充的非常量对象的引用来传递。 译者注:POD是Plain old data structure的简称,是C++语言的标准中定义的一类数据结构,可以简单地理解只包含单纯数据类型的结构体。
  • To reuse an object that carries capacity (e.g., std::string, std::vector) across multiple calls to the function in an inner loop: treat it as an in/out parameter and pass by reference. 为了让处于内循环中的函数调用可以重复使用带有容量的对象(例如std::string,std::vector):把它看做输入/输出参数并通过引用传递。
Example(示例)

struct Package {      // exceptional case: expensive-to-move object
    char header[16];
    char load[2024 - 16];
};

Package fill();       // Bad: large return value
void fill(Package&);  // OK

int val();            // OK
void val(int&);       // Bad: Is val reading its argument

译者注:示例代码说明的是POD使用引用传递输出值,而小数据者应该直接使用返回值。

Enforcement(实施建议)
  • Flag reference to non-const parameters that are not read before being written to and are a type that could be cheaply returned; they should be "out" return values. 警告那些没有在写之前读(没有输入用途)而且可以低成本返回的参数,它们应该作为返回值输出。
  • Flag returning a const value. To fix: Remove const to return a non-const value instead. 警告返回常数值的状况。修改方法:去掉常量修饰,返回一个非常量。

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则ES.50:不要执行去掉const属性的转换

    It makes a lie out of const. If the variable is actually declared const, modifyi...

    面向对象思考
  • C++核心准则​Con.3:默认情况下,传递参照常量的指针或引用

    To avoid a called function unexpectedly changing the value. It's far easier to r...

    面向对象思考
  • C++核心准则C.152:永远不要将派生类数组的指针赋值给基类指针

    Subscripting the resulting base pointer will lead to invalid object access and p...

    面向对象思考
  • C++核心准则ES.50:不要执行去掉const属性的转换

    It makes a lie out of const. If the variable is actually declared const, modifyi...

    面向对象思考
  • TAF 必修课(三):Server 启动全过程

    本节对 Taf-server整个启动流程进行解析,思考多协议支持,开发运营一体化。

    serena
  • 卫星导航信号模拟器在海军工程大学的使用案例

    卫星导航信号模拟器在海军工程大学成功使用,卫星导航信号模拟器模拟GPS定位导航授时信号,用于组合导航接收的研发、生成、检定。同时也选配测试评估软件系统,对学术实...

    时频专家
  • (译)SDL编程入门(17)鼠标事件

    和按键一样,SDL也有事件结构来处理鼠标事件,如鼠标运动、鼠标按钮按下和鼠标按钮释放。在本教程中,我们将制作一堆可以与之交互的按钮。

    arcticfox
  • 推荐18-Laravel scout 与 elasticsearch 案例

    如果一切正常,elastic 默认会在本机的 9200 端口运行,请求该端口,会获得以下

    猿哥
  • 编程问题求助小技巧

    不经意见,又写了一个bug,不仅如此,还不知道为什么出现这样的bug。于是你准备求助另外一个写bug的人。

    编程珠玑
  • 盘点|中国下一个十年的大趋势

    很多人其实到现在也没弄明白他们是怎么赚钱的,很多人都会把自己的成功归结为能力的结果,事实上这个是最大的可悲……突然发现所有的成功失败,很大程度上都不是自己个人能...

    灯塔大数据

扫码关注云+社区

领取腾讯云代金券