【发布时间】:2012-08-07 10:11:39
【问题描述】:
假设我有一个 std::tuple 由以下类型组成
struct A {
static void tip();
};
struct B {
static void tip();
};
struct Z {
};
std::tuple<const A&,const B&,const Z&> tpl;
是的,我需要单独的 A、B。 (::tip() 的实现因每种类型而异。)我尝试实现的是一个类型敏感的“访问者”,它从头到尾遍历元组。在访问T 类型的特定元素时,应根据T 是否具有::tip() 方法来调用函数。在上面的简单示例中,只有A 和B 实现了::tip() 而Z 没有实现。因此,迭代器应该为使用 ::tip() 方法的类型调用两次函数,然后调用另一个函数。
这是我想出的:
template< int N , bool end >
struct TupleIter
{
template< typename T , typename... Ts >
typename std::enable_if< std::is_function< typename T::tip >::value , void >::type
static Iter( const T& dummy , const std::tuple<Ts...>& tpl ) {
std::cout << "tip\n";
std::get<N>(tpl); // do the work
TupleIter<N+1,sizeof...(Ts) == N+1>::Iter( std::get<N+1>(tpl) , tpl );
}
template< typename T , typename... Ts >
typename std::enable_if< ! std::is_function< typename T::tip >::value , void >::type
static Iter( const T& dummy , const std::tuple<Ts...>& tpl ) {
std::cout << "no tip\n";
std::get<N>(tpl); // do the work
TupleIter<N+1,sizeof...(Ts) == N+1>::Iter( std::get<N+1>(tpl) , tpl );
}
};
template< int N >
struct TupleIter<N,true>
{
template< typename T , typename... Ts >
static void Iter( const std::tuple<Ts...>& tpl ) {
std::cout << "end\n";
}
};
我在迭代器位置使用元素类型的dummy 实例,并通过enable_if 决定调用哪个函数。不幸的是,这不起作用/不是一个好的解决方案:
- 编译器抱怨递归实例化
-
const T& dummy不是一个干净的解决方案
我想知道enable_if 是否是做出决定的正确策略,以及如何递归遍历std::tuple 捕获第一种类型并保持所有剩余参数处于重要状态。通读How to split a tuple?,但它没有做任何决定。
如何在 C++11 中以正确且可移植的方式实现这样的事情?
【问题讨论】:
-
我怀疑这个或类似的东西可能已经在 Boost.Fusion 中实现了。可能值得检查。