Good morning all!
reading stack overflow for a long time, but this is my first post here.
For some reasons I would like to do something like this:
class Base{
...
}
class A : public Base{
...
}
class B : public Base{
...
}
std::tuple<A, B> myTuple{A{}, B{}};
std::array<Base*, 2> myArray{...};
Briefly - I want to store dozens of objects in a tuple object, but at some point I need a container of pointers to all of those elements. All of them inherits from the same class which is my interface class.
And I don't know how to extract elements from myTuple, take pointers to all its elements (in exact the same sequence as it is defined) and assign them to myArray.
I have seen some solutions in different questions, but none of it fits to my specific case. I am just learning templates, so this is kinda difficult for me.
Code taken from: https://stackoverflow.com/a/59561746/19163017
template <class Tuple>
struct make_array;
template <class V, template <V N> class C, V... Ns>
struct make_array<std::tuple<C<Ns>... >> {
static constexpr Tf::TaskFlow<3>::TaskArray value{&Ns... };
};
template <class Tuple>
constexpr auto make_array_v = make_array<Tuple>::value;
But maybe it could be modified for my needs?
It is possible to create an array of pointers to tuple members using various compile time programming techniques. Below is one implementation. There may be a less verbose way of doing this, but I am no expert on this kind of stuff:
#include <iostream>
#include <string>
#include <array>
#include <tuple>
class Base {
public:
virtual std::string foo() = 0;
};
class A : public Base {
public:
std::string foo() override {
return "A";
}
};
class B : public Base {
public:
std::string foo() override {
return "B";
}
};
template<size_t I, typename... Ts>
void tuple_to_base_ptr_array_aux(std::tuple<Ts...>& tup,
std::array<Base*, sizeof...(Ts)>& ary) {
if constexpr (I < sizeof...(Ts)) {
ary[I] = static_cast<Base*>( &(std::get<I>(tup)) );
tuple_to_base_ptr_array_aux<I + 1>(tup, ary);
}
}
template<typename... Ts>
std::array<Base*, sizeof...(Ts)> tuple_to_base_ptr_array( std::tuple<Ts...>& tup) {
std::array<Base*, sizeof...(Ts)> ary;
tuple_to_base_ptr_array_aux<0>(tup, ary);
return ary;
}
int main() {
std::tuple<A, B, A, A, B, A> foo;
auto ary = tuple_to_base_ptr_array(foo);
for (auto* ptr : ary) {
std::cout << ptr->foo();
}
std::cout << "\n";
return 0;
}