我有一个函数可以获取一个样本(std::vector<double>
)作为输入并计算样本的平均值:处理空输入向量的最佳方法是什么?
我的第一个想法是抛出一个例外,就像在这个片段中一样:
double average(const std::vector<double>& sample)
{
size_t sz = sample.size();
if (sz==0) throw std::exception("unexpected empty vector");
double acc = 0;
for (size_t i=0; i<sz; ++i) acc += sample[i];
return acc/sz;
}
但我认为另一种解决方案可能是返回NaN:
double average(const std::vector<double>& sample)
{
size_t sz = sample.size();
if (sz==0) return std::numeric_limits<double>::quiet_NaN();
double acc = 0;
for (size_t i=0; i<sz; ++i) acc += sample[i];
return acc/sz;
}
我喜欢这个例外,因为它显示了问题发生的地方,而如果我在长时间计算的最终结果中得到一个NaN,那么我将更难理解NaN诞生的地方。无论如何,对于NaN,我喜欢返回一个“特殊”双重来表示意外事件发生的可能性。
还有其他方法可以处理空载体吗? 谢谢。
答案 0 :(得分:4)
我认为NaN
在数学上会更正确。最后它是0.0/0
。如果它是一个直接的分裂,会发生什么?
请注意,关于C ++和例外,存在神圣的战争。例如,请阅读:To throw or not to throw exceptions?
答案 1 :(得分:2)
我会将行为保留为未定义。
只需为非空案例编写代码,让调用者考虑正确使用它。可能你不会为空矢量调用它,因为空输入的检查可能会提前完成。
答案 2 :(得分:1)
您对使用例外的理解是正确的,您应该采用这种方法。例外是为了这个目的(throw
当出现异常情况时)。
在这种情况下,假设您返回NaN
,那么每当您调用函数average()
时,您必须确保这一点,您需要额外检查一下{{1}情景。
[注意:最重要的是,确保条件NaN
不是经常发生的情况。 IMO,如果频繁抛出,我不会使用例外。]
答案 3 :(得分:1)
我会抛出,只是为了保持安全,并确保立即检测到错误,而不是如你所说,过了一会儿。
实际上在这个特定的用例中你可以返回0,如果有意义的话说0是“无”的平均值。
我们通常做的是在我们进入方法后立即验证参数,如果我们抛出ArgumentNullException或OutOfRangeException,如果该方法实际上只是用非null和正确填充的参数调用。