卡在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中执行此操作?
答案 0 :(得分:8)
在Bristol for 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可以是硬编码的,也可以是参数函数对象或任何你想要的。
答案 1 :(得分:3)
如果需要为元组中的每个对象调用相同的模板化函数,则可以使用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;
}
答案 2 :(得分: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);
}