There is often a need to get a readable type name at runtime:
#include <iostream> #include <typeinfo> template <class T> void do_something(const T& x) { if (x == 0) { std::cout << "Error: x == 0. T is " << typeid(T).name() << std::endl; } // ... }
However, the example from earlier is not very portable. It does not work when RTTI is disabled, and it does not always produce a nice human-readable name. On some platforms, code from earlier will output just i
or d
.
Things get worse if we need a type name without stripping the const
, volatile
, and references:
void sample1() { auto&& x = 42; std::cout << "x is " << typeid(decltype(x)).name() << std::endl; }
Unfortunately, the preceding code outputs int
in the best case, which is not what we were expecting.
In the first case, we need a human-readable type name without qualifiers. The Boost.TypeIndex
library will help us out:
#include <iostream> #include <boost/type_index.hpp> template <class T> void do_something_again(const T& x) { if (x == 0) { std::cout << "x == 0. T is " << boost::typeindex::type_id<T>() << std::endl; } // ... }
In the second case, we need to keep the qualifiers, so we need to call a slightly different function from the same library:
#include <boost/type_index.hpp> void sample2() { auto&& x = 42; std::cout << "x is " << boost::typeindex::type_id_with_cvr<decltype(x)>() << std::endl; }
The Boost.TypeIndex
library has a lot of workarounds for different compilers and knows the most efficient way to produce a human-readable name for the type. If you provide a type as a template parameter, the library guarantees that all the possible type related computations will be performed at compile time and code will work even if RTTI is disabled.
cvr
in boost::typeindex::type_id_with_cvr
stands for const
, volatile
, and reference. That makes sure that the type won't be decayed.
All the boost::typeindex::type_id*
functions return instances of boost::typeindex::type_index
. It is very close to std::type_index
; however, it additionally, it has a raw_name()
method for getting a raw type name, and pretty_name()
for getting human-readable type name.
Even in C++17, std::type_index
and std::type_info
return platform-specific type names representations that are rather hard to decode or use portably.
Unlike the standard library's typeid()
, some classes from Boost.TypeIndex
are usable with constexpr. It means that you can get a textual representation of your type at compile time if you use a specific boost::typeindex::ctti_type_index
class.
Users can invent their own RTTI implementations using the Boost.TypeIndex
library. This could be useful for embedded developers and for applications that require extremely efficient RTTI tuned for particular types.
Documentation on advanced features and more examples are available at http://boost.org/libs/type_index.