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

时间:2012-03-03 20:15:01

标签: c++ exception throw

我只是在学习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;
    }

我该怎么办?返回一个空的向量?如果我将异常抛给返回值的接收者会发生什么?

3 个答案:

答案 0 :(得分:11)

当您抛出异常时,该函数会在那里停止并执行跳转到捕获异常的任何位置。你的函数没有返回任何东西,因为函数根本没有返回。

你可以做到

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块之前可能发生这两件事

答案 1 :(得分:4)

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

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

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

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。因此,您可以使用它们来避免深层嵌套的函数调用,同时确保正确管理您的资源(内存,文件和文件)。

答案 2 :(得分:1)

  

我该怎么办?返回一个空的向量?如果我将异常抛给返回值的接收者会发生什么?

从函数返回的内容是无关紧要的,因为不会以任何方式使用返回值。执行将在该特定异常的下一次捕获时继续执行(在展开堆栈后关闭)。