I have a function for error reporting that is templated because it can report errors for many different message classes:
template <typename MSG>
void reportErr(const MSG& msg)
{
std::cout << "ERROR: " << msg.error << std::endl;
}
However, some types of message have more detailed error that can be reported or other specialized error reporting, e.g.
template<>
void reportErr(const SpecificMsg& msg)
{
std::cout << "ERROR: " << msg.error;
std::cout << ", details: " << msg.details << std::endl;
}
Since there are many types like SpecificMsg
, I'd rather not create an individual template specialization for each type. Is it possible to create a generic specialization/partial specialization for any type that has a .details
member variable?
If possible, I'd like a way to do this generally (so one specialization if it has .details
, a different one if it has .other_info
, etc).
Edit: This is explicitly asking about functions. I've seen code that does similar things to specialize template classes, but I've never encountered something that does what I want for non-member functions. I suspect it isn't hard to convert the approach used for classes to work for functions, but I haven't been able to figure out how to do it.
Edit 2: my version of gcc (4.6.3) appears not to support the full C++11 standard, so the void_t
option mentioned in the "duplicate" question doesn't work for me. My compiler complains "expected nested-name-specifier before 'type'" etc and won't even let me define void_t. As such, I've removed the C++11 tag from my question.
If I got your expectation, you can use the
choice
-trick combined withdecltype
as it happens in the following example:See it up and running on
wandbox
(using GCC 4.5.4 actually, the version you mentioned isn't available). It exploits overloading resolution to pick up a working version of the function according to the type of the message and discards all what's in between. You can add more specializations (let's call them so, even though they are not properly specializations after all) and sort them according to your preferences by adjusting thechoice
parameter as needed (the higher its value, the higher the priority of the specialization).Something similar can also be done by combining the
choice
-trick withsizeof
in a SFINAE'd based solution similar to what I shown above.In particular, here is a working example:
See it up and running on
wandbox
. The advantage is that this solution doesn't suffer from the annoying warning you receive with the previous one.I tested it with an older compiler than what you asked (GCC 4.5.4), so I'm pretty confident they both work also with GCC 4.6.x.