On Wed, 26 Apr 2023, 18:21 U.Mutlu, <um@xxxxxxxxxxx> wrote: > Hi, > I have a base class Base_t and multiple derived classes from it (like > Dog_t > and Cat_t, and so on). > I collect the base addresses of these objects in a vector. > By using this vector I then need to access the original objects. > Not just some virtual functions of the objects, but the complete original > object. > How best to do this? > > The following solution is IMO not that satisfactory. > > Is there a better way, maybe in newer C++ standards like c++20? Something > like: > auto& X = helper(pBase); // X will be of type Dog_t or Cat_t etc. > How can helper return different types? You could make it return std::variant<Cat*, Dog*> and then use std::visit to access the active pointer stored in it. So something like your Identity function that returns a variant, then do: std::visit([](auto* x){ x->print(); }, Identity(p); > Thx > > > class Base_t { ... > class Dog_t : public Base_t { ... > class Cat_t : public Base_t { ... > ... > > enum Type_t { Unknown, Base, Dog, Cat }; > > struct Identity_t > { > Type_t Type; > union > { > Base_t* pBase; > Dog_t* pDog; > Cat_t* pCat; > }; > > Identity_t() : Type(Unknown) { pBase = nullptr; } > }; > > Identity_t Identity(Base_t* pBase) > { > Identity_t I; > if ((I.pDog = dynamic_cast<Dog_t*>(pBase))) { I.Type = Dog; return I; > } > if ((I.pCat = dynamic_cast<Cat_t*>(pBase))) { I.Type = Cat; return I; > } > return I; > } > > > // And using it like this: > // p is the address of a derived object, ie. Dog_t* or Cat_t* > > auto I = Identity(p); > if (I.Type == Dog) > { // use I.pDog to access it > auto& X = *I.pDog; > X.print(); > } > else if (I.Type == Cat) > { // use I.pCat to access it > auto& X = *I.pCat; > X.print(); > } > > ... > // end of code > >