Issue
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.
Solution
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...
Answered By - fabian Answer Checked By - David Marino (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.