抛出异常并返回函数的结果

Throw exception and return result from a function

本文关键字:结果 函数 返回 抛出异常      更新时间:2023-10-16

我只是在学习C++,想抛出一个异常,但我的函数结果会是未定义的???

 std::vector<myStruct> extract_notworking(std::vector<myStruct>& avec){
        std::vector<myStruct> result;
        if (avec.size() == 0)
            //throw domain_error("Cannot operate on empty vector!");
            //Cannot use exception for it would yield undefined result
            return result;
        //do something here
        //...
        return result;
    }

我该怎么办?是否返回空矢量?如果我将异常抛出给返回值的接收器,会发生什么?

当抛出异常时,函数会在那里停止,执行会跳到捕捉到异常的位置。您的函数不返回任何内容,因为该函数根本不返回。

你可以直接做

if (avec.empty())
    throw domain_error("Cannot operate on empty vector!");

您的函数将从那里退出。

请注意,您不需要关心返回值("一个函数怎么能不返回任何东西?"等),因为即使您尝试,也无法访问抛出(且未捕获)异常的函数的返回值。

例如,如果你做

try {
    std::vector<myStruct> vec;
    std::vector<myStruct> retval = extract_notworking(vec);
    print_vector(retval); // this line is only executed if extract_networking
                          // does not throw an exception
} catch (const domain_error& e) {
    // we can't access retval here so no worries
}

只有当函数正确返回(即不抛出)时,才能访问retval。在本例中,函数将抛出,因为vec为空,因此永远不会调用print_vector

即使你这样做:

std::vector<myStruct> retval;
try {
    std::vector<myStruct> vec;
    retval = extract_notworking(vec);
    print_vector(retval);
} catch (const domain_error& e) {
    // we can access retval here but the assignment never happened
}

由于函数没有返回,因此没有将其返回值分配给retval,并且retval仍然是一个完全正常的默认构造的vector,您可以自由使用。因此,在该示例中,retval没有被分配,retval也没有被打印,因为extract_networking抛出了一个异常,在这两件事发生之前,执行就跳到了catch块中。

当您throw是一个异常时,您不能return,反之亦然。您可以将异常视为针对异常情况和错误而设计的通用return。考虑这个功能:

int f(bool b) {
    if (b)
        return 42;
    throw std::runtime_error("Runtime error!");
}

当我们调用它时,我们可以在表达式中捕获它的正常返回值(在本例中为int),或者我们可以使用具有正确类型的catchtry块捕获它的异常返回值(std::runtime_error):

try {
    int normal_result = f(b);
    // Use normal result.
    // (Exceptional result does not exist.)
    std::cout << normal_result << 'n';
} catch (const std::exception& exceptional_result) {
    // Use exceptional result.
    // (Normal result does not exist.)
    std::cout << exceptional_result.what() << 'n';
}

当然,异常的威力来自于这样一个事实,即它们在调用堆栈中向上传播,直到达到匹配的catch。因此,您可以使用它们来逃离深度嵌套的函数调用,同时确保您的资源(内存、文件和c)得到正确管理。

我该怎么办?是否返回空矢量?如果我将异常抛出给返回值的接收器,会发生什么?

函数返回的内容无关紧要,因为返回值不会以任何方式使用。执行将在该特定异常的下一个catch处继续(在展开堆栈后偏离路线)。

相关文章: