忽略函数的引用返回结果

Ignoring a return-by-reference result from a function

本文关键字:返回 结果 引用 函数      更新时间:2023-10-16

假设我有一个函数,它返回一个重要结果和几个不重要的结果。我声明它,以便通过引用返回不重要的结果:

int CalculateStuff(int param1, int param2, int& result1, int& result2);

我想调用这个函数来计算一些东西,但在调用现场我想忽略不重要的结果。我可以这样做:

...
int dummy1, dummy2;
int result = CalculateStuff(100, 42, dummy1, dummy2);
... // do something with the result

我想考虑另一种不声明虚拟变量的方法:

int result = CalculateStuff(100, 42, *new int, *new int);

这有内存泄漏(不可接受),但有一个优点,可以比"虚拟"名称更清楚地显示我的意图(忽略结果)。

那么,如果我这样写会发生什么呢?
int result = CalculateStuff(100, 42, auto_ptr(new int).get(), auto_ptr(new int).get());

是否合法?当函数代码执行时,临时整数是否仍然存在?我应该用unique_ptr而不是auto_ptr吗?

请不要建议重构我的代码;我可能会-但首先我想了解这些东西是如何工作的)

这是合法的;auto_ptr对象将保持活动,直到表达式结束(即函数调用)。但它丑得要命。

重载你的函数:

int CalculateStuff(int param1, int param2, int& result1, int& result2);
int CalculateStuff(int param1, int param2) { 
    int r1=0, r2=0; 
    return CalculateStuff(param1, param2, r1, r2);
}

根据Bjarne Stroustrup的说法,如果一些参数是可选的,那么将它们设置为指针类型是一个理想的情况,这样你就可以在不需要为它们传递参数时传递NULL:

int CalculateStuff(int param1, int param2, int * result1, int * result2);

和使用:

int result = CalculateStuff(100, 42, NULL, NULL);

所有其他替代方案都不如这个好,或者至少没有优于

当然,CalculateStuff的实现必须检查参数是否为NULL

我的建议是:如果你必须问一个SO来弄清楚代码及其语义的正确性,那么代码无法清楚地表达你的意图

我认为第一个版本(dummy1dummy2)是最透明的,显然是正确的。

如果您发现自己反复调用函数而不想要可选的结果,您可以提供一个重载:

int CalculateStuff(int param1, int param2, int& result1, int& result2) {}
int CalculateStuff(int param1, int param2) {
  int unwanted1, unwanted2;
  return CalculateStuff(param1, param2, unwanted1, unwanted2);
}

如果您可以控制函数,建议的方法是:返回包含所有结果的std::tuple(或boost::tuple)或编写不需要额外变量的重载

您可以创建一个类来提供对int&的隐式(或显式)转换。

struct ignored
{
   int n;
   operator int&() { return n; }
};
n = CalculateStuff(a, b, ignored(), ignored());

这是合法的,但不能保证不泄漏内存,参见问题3例如:

实现可选输出的正确且惯用的方法是pass一个指针,传递NULL当你不想要的结果,和测试在通过指针写入之前,在函数中查找NULL