lo tolmencre lo tolmencre - 2 months ago 7
C++ Question

Excpetion Message: Insert String Representation of Faulty Value

I want to throw an exception of type

domain_error
if
key
of type
T
is not a valid key.
But I don't know how I could convert any type
T
to a string, as long as
T::operator std::string()
is defined, as for instance
int
does not support this.

This is obvioulsy wrong, as it only works for very specific types:

throw std::domain_error("key error: "+static_cast<std::string>(key));


How can this be done?

edit



My solution after the suggestion to use template specilisation

template <class T> std::string to_string(const T t)
{
return static_cast<std::string>(t);
}

template <> std::string to_string<unsigned int>(const unsigned int i)
{
std::stringstream ss;
std::string ret;
ss << i;
ss >> ret;
return ret;
}


...

std::string domain_error(const IS& is) const
{
using namespace IDTranslator_detail;
return "key error: "+to_string(is), "error";
}


...

throw std::domain_error(domain_error(key));

Answer

It can't be done, as described, in 100% of all situations.

You must specify that a part of the contract for your template is that whatever class is passed as a parameter it must support operator std::string.

You could also write, as part of your contract, that numeric types would also be allowed, and you will implement this in your template, as a specialization that uses std::to_string.

For a robust implementation, in this situation I would use SFINAE to try std::to_string, operator std::string, and if both fail, use some bland label, like "unknown type" in the exception message. Maybe use typeid together with my compiler's demangler to, at least, get a C++ type name out of it.