哪个学校的报告功能失败更好

doc*_*doc 8 c c++ return return-value

通常你有一个函数,对于给定的参数,它不能生成有效的结果,或者它不能执行某些任务.除了在C/C++世界中不常用的例外之外,基本上有两个学校报告无效结果.

第一种方法将有效返回与不属于函数的codomain的值(通常为-1)混合并指示错误

int foo(int arg) {
    if (everything fine)
        return some_value;
    return -1; //on failure
}
Run Code Online (Sandbox Code Playgroud)

第二种方法是返回函数状态并将结果传递给引用

bool foo(int arg, int & result) {
     if (everything fine) {
         result = some_value;
         return true;
     }
     return false;  //on failure
}
Run Code Online (Sandbox Code Playgroud)

您更喜欢哪种方式?为什么?第二种方法中的附加参数是否会带来显着的性能开销?

Ada*_*ght 15

对于异常和意外错误,请勿忽略异常.

然而,只是回答你的观点,问题最终是主观的.关键问题是考虑让消费者更容易使用什么,同时悄悄地轻推他们以记住检查错误状况.在我看来,这几乎总是"返回一个状态代码,并将值放在一个单独的引用中",但这完全是一个人的个人观点.我这样做的论点......

  1. 如果您选择返回混合值,那么您已经将返回的概念重载为"有用值错误代码".重载单个语义概念可能会导致混淆正确的事情.
  2. 您通常无法在函数的codomain中轻松找到值以作为错误代码加入,因此需要在单个API中混合和匹配两种类型的错误报告.
  3. 几乎没有机会,如果他们忘记检查错误状态,他们将使用错误代码,就好像它实际上是一个有用的结果.可以返回错误代码,并在返回引用中粘贴一些类似于null的概念,在使用时会很容易爆炸.如果使用错误/值混合返回模型,则很容易将其传递到另一个函数中,其中共域的错误部分是有效输入(但在上下文中无意义).

返回混合错误代码/值模型的参数可能很简单 - 没有额外的变量浮动,一个.但对我来说,危险比有限的收益更糟糕 - 人们很容易忘记检查错误代码.这是例外的一个论点 - 你实际上不能忘记处理它们(如果你不这样做,你的程序就会熄火).


bra*_*ing 8

boost optional是一项出色的技术.一个例子将有所帮助.

假设您有一个返回double的函数,并且您希望在无法计算时表示错误.

double divide(double a, double b){
    return a / b;
}
Run Code Online (Sandbox Code Playgroud)

在b为0的情况下该怎么做;

boost::optional<double> divide(double a, double b){
    if ( b != 0){
        return a / b;
    }else{
        return boost::none;
    }
}
Run Code Online (Sandbox Code Playgroud)

像下面一样使用它.

boost::optional<double> v = divide(a, b);
if(v){
    // Note the dereference operator
    cout << *v << endl;
}else{
    cout << "divide by zero" << endl;
}
Run Code Online (Sandbox Code Playgroud)

  • +1,当我看到这个问题时,这是我的直觉,我很高兴我不是唯一一个.这与Haskell中的`Maybe`结构完全一致,当然非常自然. (3认同)

小智 6

当您开始使用模板时,特殊返回值的想法完全崩溃了.考虑:

template <typename T>
T f( const T & t ) {
   if ( SomeFunc( t ) ) {
      return t;
   }
   else {         // error path
     return ???;  // what can we return?
   }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们无法返回明显的特殊值,因此抛出异常实际上是唯一的方法.返回必须检查的布尔类型并通过引用传递真正有趣的值会导致可怕的编码风格.

  • http://stackoverflow.com/questions/3157098/whats-the-right-approach-to-return-error-codes-in-c/3157182#3157182 (2认同)