C ++ 11: creating std :: tuple from a template function

I have the following function:

template<class T> T Check(int index); 

How to write a function, CheckTuple , which, given the type of a tuple, fills a tuple with Check calls?

For instance:

 CheckTuple< std::tuple<int, float, std::string> >() 

will return the following tuple:

 std::make_tuple( Check<int>(1), Check<float>(2), Check<std::string>(3) ) 

Other issues I see include unpacking a given tuple, rather than creating this method.

+6
source share
2 answers

The implementation of what you are looking for becomes quite simple using C ++ 14 integer_sequence . If you don't have this, here is a C ++ 11 implementation written by Jonathan Wackel .

 template<typename Tuple, int... I> Tuple CallCheck(std::integer_sequence<int, I...>) { return std::make_tuple(Check<typename std::tuple_element<I, Tuple>::type>(I)...); } template<typename Tuple> Tuple CheckTuple() { return CallCheck<Tuple>(std::make_integer_sequence<int, std::tuple_size<Tuple>::value>()); } // Use it as auto tup = CheckTuple<std::tuple<int, float, std::string>>(); 

Live demo

+4
source

Here is my working test implementation. (Perhaps someone has an idea how to improve it in terms of brevity. Is there any way to get rid of TupleInfo?)

 #include <typeinfo> #include <tuple> #include <iostream> template<class T> T Check(int i) { std::cout << "getting a " << typeid(T).name() << " at position " << i << std::endl; return T(); } template<typename Signature> struct TupleInfo; template<class T, class... Args> struct TupleInfo< std::tuple<T, Args...> > { using Head = T; using Tail = std::tuple<Args...>; }; template<int N, class Tuple> struct TupleChecker { static Tuple CheckTuple() { auto t = std::make_tuple(Check<typename TupleInfo<Tuple>::Head>(N)); return std::tuple_cat(t, TupleChecker<N+1, typename TupleInfo<Tuple>::Tail >::CheckTuple()); } }; template<int N> struct TupleChecker<N, std::tuple<> > { static std::tuple<> CheckTuple() { return std::tuple<>(); } }; template<class Tuple> Tuple CheckTuple() { return TupleChecker<1, Tuple>::CheckTuple(); } int main() { std::tuple<> t0 = CheckTuple<std::tuple<> >(); std::tuple<int> t1 = CheckTuple<std::tuple<int> >(); std::tuple<int, float, std::string> t2 = CheckTuple<std::tuple<int, float, std::string> >(); return 0; } 
+2
source

Source: https://habr.com/ru/post/980966/


All Articles