#include <iostream>
#include <type_traits>
#include <typeinfo>
using namespace std;
template<typename … Types>
struct xtuple
{
static constexpr int Size = 0;
};
template<typename T, typename … Types>
struct xtuple<T, Types …> : xtuple<Types …>
{
T value;
static constexpr int Size = xtuple<Types …>::Size + 1;
xtuple() = default;
xtuple(const T& t, Types … args) : value(t), xtuple<Types …>(args …) {}
};
template<int N, typename T> struct xtuple_get
{
};
template<typename T, typename … Types>
struct xtuple_get<0, xtuple<T, Types …>>
{
using VT = T;
using TT = xtuple<T, Types …>;
};
template<int N, typename T, typename … Types>
struct xtuple_get<N, xtuple<T, Types …>>
{
using VT = typename xtuple_get<N – 1, xtuple<Types …>>::VT;
using TT = typename xtuple_get<N – 1, xtuple<Types …>>::TT;
};
template<int N, typename T, typename … Types>
typename xtuple_get<N, xtuple<T, Types …>>::VT xget(xtuple<T, Types …>& xt)
{
using TT = typename xtuple_get<N, xtuple<T, Types …>>::TT;
return static_cast<TT&>(xt).value;
}
int main()
{
int v0 = 10101;
xtuple<int> a(1);
xtuple<int, short, double> b(v0,2,3.4);
cout << xget<0>(b) << endl;
cout << xget<1>(b) << endl;
cout << xget<2>(b) << endl;
}