jeudi 5 février 2015

Applying func to elements in std::tuple in the natural (not reverse) order

I need to call a - template or overloaded - function for each element in an arbitrary tuple. To be precise, I need to call this function on the elements as they are specified in the tuple.


For example. I have a tuple std::tuple <int, float> t{1, 2.0f}; and a functional



class Lambda{
public:
template<class T>
void operator()(T arg){ std::cout << arg << "; "; }
}


I need some struct/function Apply, which, if called like Apply()(Lambda(), t) would yield:


1; 2.0f;


and NOT 2.0f; 1.


Note that I know the solution, if a "raw" parameter pack is passed in to the function and I know how to do that for tuples in the reverse order. But the following attempt of partially specializing Apply fails:



template<class Func, size_t index, class ...Components>
class ForwardsApplicator{
public:
void operator()(Func func, const std::tuple<Components...>& t){
func(std::get<index>(t));
ForwardsApplicator<Func, index + 1, Components...>()(func, t);
}
};

template<class Func, class... Components>
class ForwardsApplicator < Func, sizeof...(Components), Components... > {
public:
void operator()(Func func, const std::tuple<Components...>& t){}
};

int main{
ForwardsApplicator<Lambda, 0, int, float>()(Lambda{}, std::make_tuple(1, 2.0f));
}


The code is compiled but only the first argument is printed. However, if I replace the ForwardsApplicator specialization with



template<class Func, class... Components>
class ForwardsApplicator < Func, 2, Components... >{...}


it works correctly - but, of course, only for tuples with length 2. How do I do that - if possible, elegantly -- for tuples of arbitrary length?


Aucun commentaire:

Enregistrer un commentaire