当我们想要维护调用者状态时,包装一个修改其参数的函数

Wrapper around a function that modifies its arguments when we want to maintain caller state

围绕修改其参数(输出参数)的函数创建包装器是否是一种好的做法,并且我们希望保持调用者状态?

有没有更好的方法来实现这个?

下面的示例是一个递归函数,它将在每次递归时修改其参数。我们通过引用传递以保存副本。问题是它会修改调用者状态,这种副作用必须由用户考虑。

// Wrapper to return by value
// Example of caller
T1 data_1 = ...
T2 data_2 = ...

T3 result = foo(data_1, data_2);

T3 foo(T1 data_1, T2 data_2) // copy
{
    T3 result{};

    foo(data_1, data_2, result);

    return result;
}

void foo(T1 &data_1, T2 &data_2, T3 &result)
{
    // ...
    foo(data_1.modify(), data_2.modify(), result);
}

// Alternative, out parameter by reference, will modify data_1 and data_2
// Example of caller
T1 data_1 = ...
T2 data_2 = ...

T3 result{};

foo(data_1, data_2, result);



void foo(T1 &data_1, T2 &data_2, T3 &result)
{
    // ...
    foo(data_1.modify(), data_2.modify(), result);
}

这很好,如果您在移动语义之前编写了代码,这并不少见,尤其是对于可能在复制省略方面较弱的旧编译器。

正如您所说,它更清晰,通常优化得很好,并且节省了在调用站点声明本地临时对象的时间。

如果您有一个无法移动或默认构造的类型,您仍然可以回退到旧界面。