次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
かどうかに応じて関数を呼び出す必要があります。上記の簡単な例では実装しているとは限りません。したがって、反復子は、メソッドを使用して型の関数を 2 回呼び出し、もう 1 つの関数を 1 回呼び出す必要があります。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で、そのようなものを正しく移植可能な方法で実装するにはどうすればよいですか?