C ++在函数中引发异常并在调用方中捕获它吗?

时间:2019-06-03 12:58:28

标签: c++ exception

我有一个返回“向量”的函数。但是,有时函数在运行时会遇到错误,该函数不应返回向量,而是返回可以由调用方检查的值。我应该通过引发异常并将其捕获在调用方中来处理此问题,还是应该将函数的返回类型更改为存储返回值(0或1)和向量的'std :: pair'。如果出现这种情况,我不想退出并显示“ std :: runtime”错误程序。

std::vector<int> function() {

std::vector ans;
//do stuff

if (something happens)
    return -1;

return ans;

}  

3 个答案:

答案 0 :(得分:4)

这听起来是个例外的好时机。构造一个具有构造函数参数的可抛出类型,这种代码可以解释问题。捕获器可以检查该代码。

人们会建议使用std::variant之类的方法,但是这样会很快变得混乱,并导致函数签名迅速膨胀。这也会使调用站点上的代码复杂化。这里没有必要。异常是为该用例设计的。

答案 1 :(得分:3)

我的首选是std::variant(比std::optional更好,因为它可以在出现错误的情况下提供额外的信息,这在将来永远是有益的):

usign ErrorType = int;
using ReturnType = std::variant<std::vector<int>, ErrorType>

ReturnType function() {

    std::vector ans;
    //do stuff

    if (something happens)
        return -1;

    return ans;
}

如果您的错误非常少见,并且异常可能是更深层次的呼叫者咳嗽,那么异常也是一种好/更好的方法:

class MyException : public std::exception {
public:
    MyException(int errorCode) : exception("MyException"), errorCode(errorCode)
    {}

    int code() const { return errorCode; }
private:
    int errorCode;
};

std::vector<int> function() {

    std::vector ans;
    //do stuff

    if (something happens)
        throw MyException{ -1 };

    return ans;
}

请记住,在C ++中,异常是以这样的方式设计的:在不抛出任何异常时,它们的成本为零。权衡的是,抛出异常退出堆栈非常慢(在某些cpp-con上,有人说它慢了40倍,我没有测量)。这就是使用std::optionalstd::variant(而不是例外)如此有益的原因。

AFAIK标准礼节正在new kind of exceptions机制上运作,该机制的行为类似于std::variant(在Swift中是类似的)。

答案 2 :(得分:-1)

您可以使用std::optional