我只是在学习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;
}
我该怎么办?返回一个空的向量?如果我将异常抛给返回值的接收者会发生什么?
答案 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)
我该怎么办?返回一个空的向量?如果我将异常抛给返回值的接收者会发生什么?
从函数返回的内容是无关紧要的,因为不会以任何方式使用返回值。执行将在该特定异常的下一次捕获时继续执行(在展开堆栈后关闭)。