In the following example I would expect not stdout : Base Foo Bar
, but I get P4Base P4Base P4Base
:
#include <iostream>
#include <typeinfo>
#include <vector>
#include <memory>
class Base {};
class Foo : public Base {};
class Bar : public Base {};
using Collection = std::vector<std::unique_ptr<Base> >;
int main() {
Collection collection;
collection.push_back(std::make_unique<Base>());
collection.push_back(std::make_unique<Foo>());
collection.push_back(std::make_unique<Bar>());
for (auto &u:collection)
std::cout << typeid(u.get()).name() << std::endl;
}
Is there a way to properly identify which kind of instance I have in my collection?
EDIT
A Working example after the advice of eerorika
struct Base {virtual ~Base() = default;};
struct Foo : public Base {};
struct Bar : public Base {};
using Collection = std::vector<std::unique_ptr<Base> >;
int main() {
Collection collection;
collection.push_back(std::make_unique<Base>());
collection.push_back(std::make_unique<Foo>());
collection.push_back(std::make_unique<Bar>());
for (auto &u:collection)
std::cout << typeid(*u).name() << std::endl;
}
Typeinfo how to get the name/id of the class in a polymorphic collection?
typeid
to provide the dynamic type. Your classes are not polymorphic, so you would get the static type.typeid
to a pointer gives you the type info of the pointer type rather than type of the pointed object.To fix first and third point, provide a virtual destructor for the base. To fix second:
typeid(*u).name()
Lastly, your expectation of readable class names is misguided. std::type_info::name
is not guaranteed to give you the name as you have written it for the class. The result is implementation defined, and in practice you typically get the mangled name of the type. There is no standard way to get a readable name, but there are implementation defined ways to demangle names.