如何遍历TR1元组

How to iterate over a TR1 tuple

本文关键字:TR1 元组 遍历 何遍历      更新时间:2023-10-16

被困在TR1陆地上,对于一个测试程序,我需要对一些特定类型的对象执行某些操作。我有两个元组类型定义,看起来像这样:

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;

从每个元组类型创建一个对象。然后我有类似于这样的函数模板:

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

需要对元组对象中的所有对象调用。

我如何在c++ 03中做到这一点?

刚刚在Bristol为c++ 14完成了一个特性来解决这个问题。这并不难处理。

对于更简单的情况,可以使用递归模板。虽然没有部分函数专门化之类的,但还是有点乱。

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);
}

这里的f可以是硬编码的,也可以是参数函数对象,或者任何你想要的。

如果需要为元组中的每个对象调用相同的模板函数,可以使用boost::fusion。例如

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;
}
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);
}