Ваша data
переменная std::map
содержит элементы типа std::pair<const std::string, std::shared_ptr<IContainer>>
, поэтому тип ixptr
выводится как std::shared_ptr<IContainer>
, поэтому ixptr->
возвращает указатель IContainer*
и вызывает GetThis()
по этому указателю возвращает IContainer&
независимо от того, как классы-потомки переопределяют GetThis()
. Таким образом, тип xptr
выводится как IContainer&
, и поскольку IContainer
не имеет метода GetVar2()
, поэтому xptr.GetVar2()
не удается скомпилировать.
dynamic_cast
можно использовать Чтобы решить эту проблему, например:
auto &ixptr = data.at(...);
auto &xptr = ixptr->GetThis();
auto *xptr_int = dynamic_cast<Container<int>*>(&xptr);
if (xptr_int)
{
int var2 = xptr_int->GetVar2();
...
}
Этот лог c также может быть применен к вашему for
l oop:
for (const auto &datum : data)
{
auto &xptr = datum.second->GetThis();
auto *xptr_int = dynamic_cast<Container<int>*>(&xptr);
if (xptr_int)
{
int var2 = xptr_int->GetVar2();
...
}
}
xptr_int
будет не nullptr
для "val1"
, но будет nullptr
для "val2"
, поскольку Container<int>
и Container<double>
являются отдельными и не связанными типами.