假设我有一个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
捕获第一种类型并将所有剩余的参数保持在重要状态。通读如何拆分元组?但它不做任何决定。
如何在 C++11 中以正确且可移植的方式实现这样的事情?