如何避免输出参数?

FP.*_*FP. 8 c++ oop parameters function out-parameters

我已经看到很多论据,使用返回值比out参数更可取.我确信为什么要避免它们,但我发现自己不确定我是否遇到了不可避免的情况.

我的问题的第一部分是:你最喜欢/常见的使用out参数的方法是什么?沿着这条线:人,在同行评议中,我总是看到其他程序员在这样做的时候可以轻松完成.

我的问题的第二部分涉及我遇到的一些特定情况,我想避免使用out参数,但却想不到干净的方法.

示例1:我有一个昂贵的副本,我想避免.可以在对象上完成工作,这会使对象的构建变得昂贵.建立数据的工作也不是很简单.目前,我将此对象传递给将修改对象状态的函数.对我来说,最好是新建一个工作函数内部的对象并将其返回,因为它允许我把东西放在堆栈上.

class ExpensiveCopy //Defines some interface I can't change.
{
public:
    ExpensiveCopy(const ExpensiveCopy toCopy){ /*Ouch! This hurts.*/ };
    ExpensiveCopy& operator=(const ExpensiveCopy& toCopy){/*Ouch! This hurts.*/};

    void addToData(SomeData);
    SomeData getData();
}

class B
{
public:
    static void doWork(ExpensiveCopy& ec_out, int someParam);
    //or
    // Your Function Here.
}
Run Code Online (Sandbox Code Playgroud)

使用我的函数,我得到这样的代码:

const int SOME_PARAM = 5;
ExpensiveCopy toModify;
B::doWork(toModify, SOME_PARAM);
Run Code Online (Sandbox Code Playgroud)

我想要这样的东西:

ExpensiveCopy theResult = B::doWork(SOME_PARAM);
Run Code Online (Sandbox Code Playgroud)

但我不知道这是否可行.

第二个例子:我有一个对象数组.数组中的对象是一个复杂的类型,我需要对每个元素进行处理,我希望将它与访问每个元素的主循环分开.代码目前看起来像这样:

std::vector<ComplexType> theCollection;
for(int index = 0; index < theCollection.size(); ++index)
{
    doWork(theCollection[index]);
}

void doWork(ComplexType& ct_out)
{
   //Do work on the individual element.
}
Run Code Online (Sandbox Code Playgroud)

有关如何处理这些情况的任何建议?我主要使用C++,但我很想知道其他语言是否有助于简化设置.我遇到过RVO作为一种可能的解决方案,但是我需要阅读更多内容,它听起来像编译器特定的功能.

Gle*_*len 7

我不确定你为什么要避免在这里传递引用.这些情况几乎都存在传递引用语义.

代码

static void doWork(ExpensiveCopy& ec_out, int someParam);
Run Code Online (Sandbox Code Playgroud)

看起来对我很好.

如果你真的想要修改它,那么你有几个选择

  1. 移动doWork,这样它就是ExpensiveCopy的成员(你说你不能这样做,所以那就是了)
  2. 从doWork返回(智能)指针而不是复制它.(你不想这样做,因为你想把东西放在堆栈上)
  3. 依靠RVO(其他人指出的几乎所有现代编译器都支持)