Throw an exception and return the result from the function

I am just learning C ++ and want to throw an exception, but then the result of my function will be undefined ???

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; } 

What should I do? Return empty vector? What happens if I throw an exception to the recipient of the return value?

+7
source share
3 answers

When you throw an exception, the function stops there, and execution moves to where the exception was detected. Your function does not return anything, because the function does not return at all.

You can just do

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

And your function will exit it.

Note that you donโ€™t have to worry about the return value (โ€œHow can a function not return anything?โ€, Etc.) because you cannot access the return value of a function that threw (and did not break) the exception even if you try.

So for example, if you do

 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 } 

You can only access retval if the function returns correctly (i.e. does not throw away). In the example, your function will throw because vec empty, so print_vector will never be called.

Even if you do this:

 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 } 

Since the function did not return, assigning its return value to retval did not happen, and retval is still an absolutely normal default built vector , which you can use freely. So in this example, retval not assigned, and retval not printed, because extract_networking throws an exception and execution into a catch before these two things can happen.

+9
source

If you throw exception, you cannot return and vice versa. You can think of exceptions as a generalized return , designed for exceptional circumstances and errors. Consider this function:

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

When we call it, we can write its normal return value (in this case a int ) in the expression, or we can fix its exceptional return value ( std::runtime_error ) using a try block with catch correct type:

 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'; } 

The power of exceptions, of course, comes from the fact that they propagate the call stack until they reach catch matching. Thus, you can use them to avoid deep nested function calls, while ensuring the proper management of your resources (memory, files, etc.).

+4
source

What should I do? Return empty vector? What happens if I throw an exception to the recipient of the return value?

What is returned from the function does not matter, since the return value will not be used in any way. Execution will continue at the next catch for this particular exception (after the course after unwinding the stack).

+1
source

All Articles