I can imagine two implementations of die
, and I have issue with both of them
template <typename... Ts>
[[noreturn]] inline bool die(std::string_view message_format = "", Ts&&... args)
{
std::cerr << std::vformat(message_format, std::make_format_args(args...));
std::abort(); // or std::exit or std::terminate
}
That is, write the message somewhere and end the program. I could imagine a project using this, but not the projects I'm involved in.
It seems most appropriate in projects large enough that you don't just return
up to main
, but small enough that killing the whole process is never overkill.
template <typename... Ts>
[[noreturn]] inline bool die(std::string_view message_format = "", Ts&&... args)
{
throw std::runtime_error(std::vformat(message_format, std::make_format_args(args...)));
}
I.e. throw a generic exception, with the message. I would prefer some granularity in the type of the exception, so that args...
could instead be a data member for the catch
. If pressed, i'd write that as
template<typename T, typename... Args>
[[noreturn]] inline bool die_with(Args&&... args)
{
throw T(std::forward<Args>(args)...);
}
things_are_ok() or die_with<things_exception>("things not ok", foo);
But there are other ways of massaging a throw
to be a bool
expression
things_are_ok() or (throw things_exception("things not ok", foo), false);