Yesterday I was working on a class to produce natural-language translations of complex C++ types, and I said that there was no general way to map a fundamental type to a name. Of course, there is:
template<typename T> class TypeDecryptor { public: static string getName() { return typeid(T).name(); } };
Of course, not quite everything in the garden is lovely. This provides an implementation-defined string, which as far as I can see is not even required to be unique for a given type. In point of fact, it’s extremely unlikely an implementation will return a non-unique string since each type has to be mapped to a string for linkage purposes anyway. The problem is that the string isn’t necessarily human-readable.
I think that on reasonable implementations there should be a function available to unmangle this string back into a human-readable type, which means you can potentially make a completely general type decryptor.
You are right, this is a pain and there should be a standard way of it.
However, you can get closer to the ideal output.
You can use template specialisation to name common types, e.g.
template string TypeDecryptor::getName (void) { return "int"; }
template string TypeDecryptor<MyClass >::getName (void) { return "MyClass"; }
You can also add per-toolchain support for demangling, e.g.
#if __GXX_ABI_VERSION > 1000
#include
template string TypeDecryptor::getName (void)
{
int s;
char *b (abi::__cxa_demangle (typeid (T).name (), NULL, NULL, &s));
//if (!b || s) throw ...;
return b;
}
#else
template string TypeDecryptor::getName (void) { return typeid (T).name (); }
#endif
boost::units::detail::demangle does pretty much this.
Of course actually doing any of this is a pain in the ass.