おことわり
クソ雑魚初心者のメモです.
問1
(Q)
A
型 N 個から成るよ.個数 N は静的に決まるよ.どう実装すればいいか?
↓
(A)
それは単純に
A As[5]; //Aが5個
とか
std::array<A,3> As; //Aが3個
とかでいいんですかね.
(Q)
その場合,全ての要素についてメソッド A::F()
呼ぶには?
↓
(A)
こんなすかね?
for( A &a : As )a.F();
問2
(Q)
A
, B
, C
から成るよ.要素の個数と,何番目が何型なのかは静的に決まるよ.
例えば { A,A,B }
とか { C,B,A,B,B }
とか.どう実装すればいいか?
↓
(A)
えっと…???
ああ,
std::tuple<A,A,B>
とか std::tuple<C,B,A,B,B>
とかでいいのか…な?
(Q)
その場合,全ての要素についてメソッド F()
を呼ぶには?
( A
,B
,C
は全てメソッド F()
を持つ型なのだとして)
↓
(A)
んん???
すいません,わかりません.ググります……
(そして2時間後……)
なんか↓で動いた気がするけど……難しすぎない?
//---------------------------
//(*1)tupleの要素を先頭から順に引数として用いて Func を呼ぶ,というのを
//ググった結果,見様見真似で書いたもの
template< std::size_t TupleIndex=0, typename Func, typename... TupleItemTypes >
inline typename std::enable_if_t< TupleIndex == sizeof...(TupleItemTypes) >
Tuple_for_each( const std::tuple<TupleItemTypes...> &, Func & ){}
template< std::size_t TupleIndex=0, typename Func, typename... TupleItemTypes >
inline typename std::enable_if_t< TupleIndex < sizeof...(TupleItemTypes) >
Tuple_for_each( const std::tuple<TupleItemTypes...> &t, Func &f )
{
f( std::get<TupleIndex>(t) );
Tuple_for_each< TupleIndex+1, Func, TupleItemTypes...>( t, f );
}
//---------------------------
//A,B,C
struct A{ void F() const { std::cout << "A "; } };
struct B{ void F() const { std::cout << "B "; } };
struct C{ void F() const { std::cout << "C "; } };
//
int main()
{
//(*2)「ジェネリックラムダ」とかいう不可思議存在
auto Func = [](auto &X){ X.F(); };
{//{A,A,B}
std::tuple<A,A,B> T;
Tuple_for_each( T, Func );
}
std::cout << '\n';
{//{C,B,A,B,B}
std::tuple<C,B,A,B,B> T;
Tuple_for_each( T, Func );
}
}
(*1) のところ, 最初,自力で
template< std::size_t TupleIndex=0, typename Func, typename... TupleItemTypes >
void My_Tuple_for_each( const std::tuple<TupleItemTypes...> &t, Func &f )
{
f( std::get<TupleIndex>(t) );
if( TupleIndex+1 < std::tuple_size_v< std::tuple<TupleItemTypes...> > )
{ My_Tuple_for_each< TupleIndex+1, Func, TupleItemTypes...>( t, f ); }
}
とか書いてみたんだけど,これだと
My_Tuple_for_each< TupleIndex+1, Func, TupleItemTypes...>( t, f );
で TupleIndex が範囲外のものを実体化しようとしてしまうのでダメであった.
enable_if
だの何だのいうのを持ってくるのは馬鹿丸出し初心者には厳しいです.C++難しすぎ.
(*2)のところでは,Tuple_for_each
を使おうにも「 Func
には何を渡せばいいんだよ?」っていうのがまた謎であった.
あと,
//こうですか? わかりません><
std::tuple<A,A,B> T;
Tuple_for_each( T, [](auto &X){ X.F(); } ); //←コンパイルエラー
とか書いてコンパイル通らなくてしばらく躓いていたが,それは単に引数の型が Func &
だからコレじゃ渡せないっていうだけの話だった.
(Tuple_for_each
をコピペして const Func &
なやつも用意すれば良いのかな.)
追記
むむ?
自力で書いて失敗した My_Tuple_for_each
についてだが,
if( TupleIndex+1 < std::tuple_size_v< std::tuple<TupleItemTypes...> > )
のところを if constexpr
とすればいけるのではあるまいか…?
↓
試してみたらOKっぽい雰囲気.