Question

Being stuck in TR1 land, for a test program I need to perform certain operations on a number of objects of specific types. I have a couple of tuple type definitions which look like this:

typedef std::tr1::tuple< bool
                       , signed char
                       , signed short
                       , signed int
                       , signed long long
                       , unsigned char
                       , unsigned short
                       , unsigned int
                       , unsigned long long >  integral_types;

From each tuple type an object is to be created. I then have function templates similar to this:

template<typename T>
void invoke_operation_1(T& obj);

These need to be called for all objects in a tuple object.

How do I do that in C++03?

Was it helpful?

Solution 2

You could use boost::fusion if you need to call the same templated function for every object in the tuple. E.g.

template<typename T>
void invoke_operation_1(T& obj)
{
    std::cout << obj << std::endl;
}

struct executor
{
    template<typename T>
    void operator()(T& t) const
    {
        invoke_operation_1(t);
    }
};

typedef boost::tuple< bool
                       , signed char
                       , signed short
                       , signed int
                       , signed long long
                       , unsigned char
                       , unsigned short
                       , unsigned int
                       , unsigned long long >  integral_types;
int main()
{
    integral_types t(true, 0, 1, 2, 3, 4, 5, 6, 7);
    boost::fusion::for_each(t, executor());
    return 0;
}

OTHER TIPS

There was a feature just finalized in Bristol for C++14 to address this very problem. It's not too hard to deal with.

For the simpler case, you can use a recursive template. It's a smidge of a mess though without partial function specialization and such.

template<typename Tup, std::size_t N> struct visit_detail {
     template<typename F> static void call(Tup& t, F f) {
         f(std::tr1::get<N>(t));
         return visit_detail<Tup, N+1>::call(t, f);
     }
};
template<typename Tup> struct visit_detail<Tup, std::tr1::tuple_size<Tup>::value> {
    template<typename F> static void call(Tup& t, F f) {}
}

template<typename Tup, typename F> void visit(Tup& t, F f) {
    return visit_detail<Tup, 0>::call(t, f);
}

Here f can be hardcoded or a parameter function object or whatever you want.

template<typename tup, typename N>
struct visit_detailImpl {
    template<typename f>
    static void call(tup& t, f f) {
        f(std::tr1::get<N::value>(t));
        return visit_detailImpl<tup, std::integral_constant<std::size_t, N::value + 1> >::call(t, f);
    }
};
template<typename tup> // end recursion struct
struct visit_detailImpl<tup, std::integral_constant<std::size_t, std::tr1::tuple_size<tup>::value> > {
    template<typename f>
    static void call(tup& t, f f) {}
};
template<typename tup, typename Fn>
void for_each_tup(tup& t, Fn f) {
    return visit_detailImpl<tup, std::integral_constant<std::size_t, 0> >::call(t, f);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top