I have a basic class looking something like this:
template <typename TCode, TCode SuccessVal>
class Error
{
public:
typedef TCode code_t;
Error(TCode code, char const *descr="Unknown Error."):
code(code), descr(descr)
{
}
...
char const *description() const
{
return descr;
}
...
private:
TCode code;
char const *descr;
};
All it does is encapsulate some kind of error code enum class so that it provides a bit more context for logging.
Now say I have a function panic:
template <typename TCode, TCode SuccessVal>
void panic(Error<TCode, SuccessVal> const &e)
{
puts("Panic!");
printf("Unrecoverable error: %s", e.description());
abort();
}
Compiling with -fdump-tree-original shows that in my case this results in a couple of distinct functions, with the exact same code. This is what you would expect, but probably not what you would desire.
An obvious route would be a base class that just had the message and a constructor taking the message, but I find that rather unattractive.
We don't ever use the error code itself so nothing we do depends on T. How can I avoid a ton of template instantiations that compile to basically the same code?
Another desirable feature would be to make sure that whatever type TCode is, it is coercible to an integer type.
An obvious factorization of this code would be this:
[[noreturn]] void panic_with_message(char const * msg)
{
std::printf("Panic!\nUnrecoverable error: %s\n", msg);
std::fflush(stdout);
std::abort();
}
template <typename T, T Val>
[[noreturn]] static inline void panic(Error<T, Val> e)
{
panic_with_message(e.description());
}
You could put only the template into a header, along with a declaration of the function, and keep the function definition in a separate translation unit. That should keep the code bloat to a minimum:
// panic.hpp
#ifndef H_PANIC
#define H_PANIC
#include "error.hpp" // for Error<T, Val>
[[noreturn]] void panic_with_message(char const * msg);
template <typename T, T Val>
[[noreturn]] static inline void panic(Error<T, Val> e)
{
panic_with_message(e.description());
}
#endif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With