If you are willing to explicitly describe the structure members you might come close to what you wanted.
#include <iostream>
#include <tuple>
#include <functional>
using namespace std;
struct test
{
int i = 121;
double j = 234.0;
string k = "Some k";
};
struct anotherStruct
{
double t = 121.8;
};
struct undescribedStruct
{
string t = "Some undescribed";
};
tuple<int&, double&, string&> struct_as_tuple(test& t)
{
return tie( t.i, t.j, t.k);
}
tuple<double&> struct_as_tuple(anotherStruct& t)
{
return tie( t.t );
}
//make_indices && Co thanks to sigidagi
//see http://cpptruths.blogspot.de/2012/06/perfect-forwarding-of-parameter-groups.html
template<unsigned...> struct index_tuple{};
template<unsigned I, typename IndexTuple, typename... Types>
struct make_indices_impl;
template<unsigned I, unsigned... Indices, typename T, typename... Types>
struct make_indices_impl<I, index_tuple<Indices...>, T, Types...>
{
typedef typename
make_indices_impl<I + 1,
index_tuple<Indices..., I>,
Types...>::type type;
};
template<unsigned I, unsigned... Indices>
struct make_indices_impl<I, index_tuple<Indices...> >
{
typedef index_tuple<Indices...> type;
};
template<typename... Types>
struct make_indices
: make_indices_impl<0, index_tuple<>, Types...>
{};
void bar()
{
std::cout << endl;
}
template <typename T, typename... Args>
void bar(T&& t, Args&&... args)
{
std::cout << "T: [" << t << "] ";
return bar(forward<Args>(args)...);
}
template <unsigned... Indices, class... Args>
void foo_forward_call_impl(index_tuple<Indices...>,
std::tuple<Args...> tuple )
{
return bar(std::get<Indices>(tuple)...);
}
template<class... Args>
void foo_forward_call(std::tuple<Args...> tuple )
{
typedef typename make_indices<Args...>::type Indices;
return foo_forward_call_impl(Indices(), tuple);
}
template <typename T>
void foo(T&& t)
{
return foo_forward_call( struct_as_tuple(t) );
}
int main()
{
test t1;
foo(t1);
anotherStruct t2;
foo(t2);
undescribedStruct t3;
//will error foo(t3);
// your code goes here
return 0;
}
You basically have to provide a tuple construction from struct members for each supported type (see struct_as_tuple).
foo then generates the tuple out of the passed in type and passes it to a tuple unrolling implementation.
It's not what you probably would like to have but it is the closest to it I can imagine at this time...