I've got a question, if we have a class A
and other classes from class B : class A
to class Z : class A
are inherited from class A
, and we have a vectorstd::vector<A>
that contains objects of all types from class A
to class Z
, how can we get an object of specific type from that vector, for example we want to get object which is type of E
how to get that object.
class A {};
class B : A {};
class C : A {};
...
class Z : A {};
std::vector<A> vec; // lets say it contains objects of type A to Z
template<typename T>
T GetObject()
{
for (int i = 0; i < vec.size(); i )
{
//if type of vec[i] == type of T return vec[i]
}
}
E obj = GetObject<E>();
I've used something like this
if (typeid(vec[i]) == typeid(T))
{
return vec[i];
}
but it doesn't work.
CodePudding user response:
You cannot store subtypes of A
in a std::vector<A>
. Any objects of a subtype you put in there are sliced and every element in the vector is simply an object of type A
.
You could use a std::vector<std::variant<A, ..., Z>>
instead. You should probably think about a different design though:
#define TYPES(x) \
x(B) \
x(C) \
x(D) \
x(E) \
x(F) \
x(G) \
x(H) \
x(I) \
x(J) \
x(K) \
x(L) \
x(M) \
x(N) \
x(O) \
x(P) \
x(Q) \
x(R) \
x(S) \
x(T) \
x(U) \
x(V) \
x(W) \
x(X) \
x(Y) \
x(Z)
#define DECLARE(x) struct x { void operator()() {std::cout << #x << '\n'; } };
#define EMPLACE(x) data.emplace_back(x{});
#define TYPE_PARAMS(x) ,x
DECLARE(A);
TYPES(DECLARE);
using Variant = std::variant<A TYPES(TYPE_PARAMS)>;
int main() {
std::vector<Variant> data;
EMPLACE(A);
TYPES(EMPLACE);
using SearchedType = E;
auto pos = std::find_if(data.begin(), data.end(), [](Variant const& v) { return std::holds_alternative<SearchedType>(v); });
if (pos != data.end())
{
std::visit([](auto& v) { v(); }, *pos);
}
}
An alternative would be to declare a template variable:
template<class T>
T object{};
int main() {
using SearchedType = E;
object<SearchedType>();
}
Another option would be to add a virtual destructor to A
and use a std::vector<std::unique_ptr<A>>
combined with dynamic_cast
...