Вам не нужно заново изобретать колесо, когда вы можете просто расширить его с помощью подходящей шины.
Стандарт C ++ дает вам typeid()
, который работает во всех случаях, включая встроенные типы, пользовательские классы, полиморфные классы, множественное наследование, виртуальное наследование и тому подобное.тот.
Теперь вам могут не понравиться имена, используемые typeid()
, которые зависят от реализации.Или вы можете расширить доступную информацию с помощью собственных расширений управления типами.В этом случае Бьярн Страуструп предложил в « Проектирование и развитие C ++ » очень простое и эффективное решение.
typeid()
возвращает ссылку на const std::type_info
.Теперь вы можете использовать адрес этого объекта в unordered_map
, чтобы сопоставить тип с вашей собственной пользовательской информацией, которая может предоставить желаемое имя.
Преимущество этого решения: использует надежную встроенную возможность, основано на одном дополнительном объекте на класс (может быть статическим), очень низкие накладные расходы, чтобы добраться до имени.все, что вам нужно сделать, это подумать о том, как лучше всего заполнить карту.
Вот небольшое и быстрое доказательство концепции (конечно, должно быть улучшено):
// Basic principle of the idea
map<const type_info*, string> mytypes;
template <class T>
const string& mytype(T &&x) {
return mytypes[&typeid(x)];
}
// Some test types
struct A { virtual int test() {} };
struct B : A {};
int main() {
// To be improved: initialization of the type info extension
mytypes[&typeid(int)]="Plain C++ integer";
mytypes[&typeid(A)]="Structure A";
mytypes[&typeid(B)]="Structure B";
// demo, including polymorphic type
int a;
A * p = new B;
cout << typeid(int).name() <<endl;
cout << mytype(a) <<endl;
cout << mytype(*p) <<endl;
return 0;
}
Демо онлайн