我有一个返回值的函数,但是在某些条件下(函数已知,但不是调用者)我希望调用者忽略该值。
例如,假设您想要计算平均海洋温度。为此,您将地球分成一百万个地块并询问每个地块的温度。但是当包裹在陆地上时,返回值需要表明该值不应包括在平均值中。
我可以想出几种方法来完成这项工作,但我不确定哪种方法是好的解决方案:
解决方案1似乎是最快和最容易实现的,但如果调用者使用该函数而不检查该值是否有效,则最有可能创建难以发现的错误。
解决方案2和3需要通过一个非常重的值,但看起来是一个不错的方法。
解决方案4需要将大量异常调用作为程序的预期部分。我没有使用此类例外的经验。
解决方案5的通用性很好(并且nullptr 感觉就像表示虚无的最佳方式一样),但是为了获得双倍而取消引用指针似乎非常低效。
我知道真正知道哪种解决方案最快的唯一方法就是全部测试,但我想知道是否有任何常见的最佳做法来处理这样的情况。< / p>
性能对我来说相对重要,因为这个函数每帧会被调用大约10,000次。
这样的问题可能有答案,但我不知道哪些搜索词描述为&#34; c ++假/忽略返回值&#34;显然不是好人。
答案 0 :(得分:3)
这似乎是一个基于意见的问题。
我的观点是,最好的方法是返回一个optional<T>
对象;如果它为空,则表示没有返回任何值,如果它是非空的,则调用者必须显式“取消引用”它才能获取值,尽管实际上没有涉及堆分配或指针。 (如果调用者忘记检查并尝试从空T
中获取optional<T>
,则会抛出异常。)您现在可以使用boost::optional
,或std::optional
一次C ++ 17问世。
这在性能方面或多或少是选项2,但具有更好的界面。
答案 1 :(得分:2)
您未列出的简单便宜的方式是通过引用传递(输出参数):
bool averageValue(int &myVal, ...) {
// calculate average
myVal = average;
if (land) {
return false;
}
return true;
}
int avgVal;
if (averageValue(avgVal, ...)) {
//add to the total val.
这可能不会像选项#1那么快(但仅仅是因为额外的比较)但它将非常接近并具有代码清晰度和没有幻数的优势。
答案 2 :(得分:1)
我曾经做过#2(boost::optional
,但最近的经验告诉我使用选项6(4的变体):
bool isValidCoord(int x, int y);
Data getData(int x, int y) {
assert(isValidCoord(x,y));
...
}
这很好地拆分,调用代码是干净的:
if(isValidCoord(x, y))
doCalculation(getData(x,y));