tags:

views:

625

answers:

3
+4  Q: 

iterate over tuple

Hello!

How can I iterate over a tuple (using C++0x)? I tried the following, but that doesn't work:

for(int i=0; i<std::tuple_size<T...>::value; ++i) 
  std::get<i>(my_tuple).do_sth();

Error 1: sorry, unimplemented: cannot expand ‘Listener ...’ into a fixed-length argument list.
Error 2: i cannot appear in a constant expression.

So, how do I correctly iterate over the elements of a tuple?

Thanks!

Niels.

+2  A: 

You need to use template metaprogramming, here shown with Boost.Tuple:

#include <boost/tuple/tuple.hpp>
#include <iostream>

template <typename T_Tuple, size_t size>
struct print_tuple_helper {
    static std::ostream & print( std::ostream & s, const T_Tuple & t ) {
        return print_tuple_helper<T_Tuple,size-1>::print( s, t ) << boost::get<size-1>( t );
    }
};

template <typename T_Tuple>
struct print_tuple_helper<T_Tuple,0> {
    static std::ostream & print( std::ostream & s, const T_Tuple & ) {
        return s;
    }
};

template <typename T_Tuple>
std::ostream & print_tuple( std::ostream & s, const T_Tuple & t ) {
    return print_tuple_helper<T_Tuple,boost::tuples::length<T_Tuple>::value>::print( s, t );
}

int main() {

    const boost::tuple<int,char,float,char,double> t( 0, ' ', 2.5f, '\n', 3.1416 );
    print_tuple( std::cout, t );

    return 0;
}

In C++0x, you can write print_tuple() as a variadic template function instead.

+5  A: 

Boost.Fusion is a possibility:

Untested example:

struct DoSomething
{
    template<typename T>
    void operator()(T& t) const
    {
        t.do_sth();
    }
};

tuple<....> t = ...;
boost::fusion::for_each(t, DoSomething());
Éric Malenfant
A: 

boost's tuple provides helper functions get_head() and get_tail() so your helper functions may look like this:

inline void call_do_sth(const null_type&) {};

template inline void call_do_sth(cons& x) { x.get_head().do_sth(); call_do_sth(x.get_tail()); }

as described in here http://www.boost.org/doc/libs/1_34_0/libs/tuple/doc/tuple_advanced_interface.html

with std::tuple it should be similar.

Actually, unfortunately std::tuple does not seem to provide such interface, so methods suggested before should work, or you would need to switch to boost::tuple which has other benefits (like io operators already provided). Though there is downside of boost::tuple with gcc - it does not accept variadic templates yet, but that may be already fixed as I do not have latest version of boost installed on my machine.

Vyacheslav Kononenko