假设我有一个返回重要结果和几个不重要结果的函数。我声明它是为了通过引用返回不重要的结果:
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
吗?
(请不要建议重构我的代码;我可能会 - 但首先我想了解这些东西是如何工作的)
答案 0 :(得分:4)
这是合法的; 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);
}
答案 1 :(得分:4)
根据Bjarne Stroustrup的说法,如果某些参数是可选的,那么它是使它们成为指针类型的理想情况,这样当你不需要为它们传递参数时你可以传递NULL
:
int CalculateStuff(int param1, int param2, int * result1, int * result2);
并使用:
int result = CalculateStuff(100, 42, NULL, NULL);
所有其他选择都不如此,或者至少不是更好。
当然,CalculateStuff
的实施必须检查参数是否为NULL
。
答案 2 :(得分:3)
如果您可以控制该函数,建议的方法是:返回包含所有结果的std::tuple
(或boost::tuple
)或写入不需要额外变量的重载。
答案 3 :(得分:3)
以下是我的建议:如果你必须要求SO弄清楚代码及其语义的正确性,那么代码就无法明确表达你的意图。
我认为第一个版本(dummy1
和dummy2
)是最透明的,显然是正确的。
如果您发现自己反复调用该函数而不想要可选结果,则可能会出现过载:
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);
}
答案 4 :(得分:3)
您可以创建一个提供隐式(或显式)转换为int&
。
struct ignored
{
int n;
operator int&() { return n; }
};
n = CalculateStuff(a, b, ignored(), ignored());
您可以进一步将其设为模板并添加const重载。
答案 5 :(得分:2)
这是合法的,但不保证不会泄漏内存,请参阅问题3 例如here。
实现可选输出的正确和惯用方法是通过
一个指针,当你不想要结果时传递NULL
并进行测试
在通过指针写入之前,函数中的NULL
。