Za sugestia @kq nowy watek, w nawiazaniu do poprzedniego.
Na poczatek kod, ktory udalo mi sie napisac
#include <iostream>
#include <tuple>
using namespace std;
template<typename A, typename B, int C>
struct base {
static constexpr auto Value = C;
using type_A = A;
using type_B = B;
int my_value() const { return C; }
};
template<typename T>
struct instance {
instance () : v (0) {}
instance (const T& v) : v(v) {}
int v;
};
template<typename T, size_t N>
struct type_generator
{
using rest_tuple = typename type_generator<T, N-1>::type;
using current_type = instance<typename std::tuple_element<N, T>::type::type_A>;
using type = decltype(
std::tuple_cat(
std::declval<rest_tuple>(),
std::declval<std::tuple<current_type>>()
)
);
};
template<typename T>
struct type_generator<T, 0>
{
using current_type = instance<typename std::tuple_element<0, T>::type::type_A>;
using type = std::tuple<current_type>;
};
template<typename M>
auto instantiate(const M &m) -> typename type_generator<M, std::tuple_size<M>::value - 1>::type
{
}
int main() {
tuple<base<int, float, 1>, base<float, double, 2>> a;
static_assert(
std::is_same<
type_generator<decltype(a), tuple_size<decltype(a)>::value - 1>::type,
tuple<instance<int>, instance<float>>
>::value == true);
return 0;
}
idea jest taka, ze mam tuple typow base, np std::tuple<base<A1, B1, C1>, base<A2, B2, C2> ...>
i konwertuje ja na tuple std::tuple<instance<A1>, instance<A2>...>
(czyli biore sobie po jednym parametrze szablonu typu base i uzywam go jako parametr szablonu typu instance). W tym momencie struktura type_generator umozliwia mi juz wygenerowanie poprawnego typu docelowego. Teraz problemem jest zainicjowanie tej tupli. Zalozylem sobie, ze klasy typu base maja jakies atrybuty, ktore chcialbym uzyc w konstruktorze typu instance. W tym przypadku to trzeci parametr szablonu, int C. Dla ulatwienia wrzucilem sobie go jakos static constexpr ale fajnie jakby mogloby to by tez byc pole nie-static, np. metoda my_value. W takim wypadku konwersja std::tuple<base<A1, B1, C1>, base<A2, B2, C2>> first_tuple
musialaby wygladac std::tuple<instance<A1>, instance<A2>> second_tuple(std::get<0>(first_tuple).my_value(), std::get<1>(first_tuple).my_value())
. I to byloby zadanie funkcji instantiate
, ktora wlasnie teraz probuje napisac i o ktora jest pytanie. :-)