Daily bit(e) C++. std::type_index, boost::type_index
Daily bit(e) C++ #201. Преобразование std::type_info
в читабельные имена типов с помощью C++11 std::type_index
и boost::type_index
.
Объект std::type_info
, возвращаемый оператором typeid
, не обеспечивает удобного для чтения человеком имени типа.
Мы можем смягчить эту проблему вручную, полагаясь на C++11 std::type_index
и вручную отслеживая преобразование между std::type_info
и любой необходимой информацией.
#include <unordered_map>
#include <string>
#include <typeindex>
#include <iostream>
struct A { virtual void fun() {} };
struct B : A {};
std::unordered_map<std::type_index, std::string> names;
void inspector(A& a) {
std::cout << names[typeid(a)] << "\n";
}
// Заполняем наш пользовательский словарь
names[typeid(A)] = "Base";
names[typeid(B)] = "Derived";
names[typeid(int)] = "int";
names[typeid(double)] = "double";
int x = 20;
double y = 2.4;
std::cout << names[typeid(x)] << "\n";
// напечатает: "int"
std::cout << names[typeid(y)] << "\n";
// напечатает: "double"
A a;
B b;
inspector(a);
// напечатает: "Base"
inspector(b);
// напечатает: "Derived"
Открыть пример на Compiler Explorer.
В качестве альтернативы, можно использовать библиотеку boost::type_index
, которая предоставляет дополнительные функции.
#include <boost/type_index.hpp>
#include <unordered_map>
#include <vector>
#include <string>
#include <iostream>
namespace bti = boost::typeindex;
struct A { virtual void fun() {} };
struct B : A {};
void inspector(A& a) {
std::cout << bti::type_id_runtime(a).pretty_name() << "\n";
}
// Информация о типе времени компиляции:
int x = 20;
double y = 2.4;
std::cout << bti::type_id<decltype(x)>().pretty_name() << "\n";
// напечатает: "int"
std::cout << bti::type_id<decltype(y)>().pretty_name() << "\n";
// напечатает: "double"
// Информация о типе времени выполнения:
A a;
B b;
inspector(a);
// напечатает: "A"
inspector(b);
// напечатает: "B"
// Также поддерживает cv-квалификаторы (const и volatile) (typeid нет)
std::cout << bti::type_id_with_cvr<const int>().pretty_name() << "\n";
// напечатает: "int const"
// Также можно распутывать сложные вложенные типы
using nested = std::unordered_map<A,std::vector<std::string>>;
std::cout << bti::type_id<nested>().pretty_name();
// напечатает(GCC): "std::unordered_map<A, std::vector<
// std::__cxx11::basic_string<char...
Открыть пример на Compiler Explorer.