Reputation: 11
I'm writing a set of functions that return a status enum class. I want to recognize whenever we hit an issue and stop the BigFunction
.
Status BigFunction()
{
Status status;
status = function1();
if (status != Status::SUCCESS)
return status;
status = function2();
if (status != Status::SUCCESS)
return status;
// Do more
return status;
}
Is there a 'neater' way to do this? It seems a little cumbersome and messy to have the if statement every time? Is there a way to get something like return_if_error function1()
instead?
Upvotes: 1
Views: 117
Reputation: 38209
On most compilers (I do not know any exceptions), exceptions are zero overhead when not thrown, but when exception is thrown unwinding stack is pretty slow (I've seen source claiming that penalty is x40 times).
For that reason many developers prefer use exceptions only for exceptional cases ;) (for things that hardly ever happen).
There is other way to meet your requirement, just use &&
operator and provide tool which can store status:
struct StatusKeeper {
bool update(Status newStatus) {
status = newStatus;
return status == Status::SUCCESS;
}
bool operator()(Status newStatus) {
return update(newStatus);
}
Status get() const {
return status;
}
operator Status () const {
return status;
}
private:
Status status = Status::SUCCESS;
};
Status BigFunction()
{
StatusKeeper status;
status(function1())
&& status(function2())
&& status(function3());
// or more verbose, but more readable:
status.update(function1())
&& status.update(function2())
&& status.update(function3());
return status;
}
Now second argument for operator &&
is evaluated only if first argument was evaluated to true
.
There is also possibility to use C macros for that purpose, but IMHO in C++ the less macros then better.
Upvotes: 2
Reputation: 1334
That's why exceptions exist. If you have no control over the behavior of function1
and function2
, you could create a helper function (e.g. check
) that throws on status != Status::SUCCESS
:
void check(Status status) {
if (status != Status::SUCCESS)
throw std::runtime_error("Status was not success");
}
Then use it instead of the if statement and wrap everything in try catch:
try {
check(function1());
check(function2());
} catch (const std::runtime_error &e) {
// error handling
}
Upvotes: 3