2013-08-09 20 views
6

このようなユーティリティを手作業で書くよりも良い解決策はありますか?このように使用することがstd :: tupleをどのように反復処理するのですか?

template <size_t> struct SizeT { }; 

template < typename TupleType, typename ActionType > 
inline void TupleForEach(TupleType& tuple, ActionType action) 
{ 
    TupleForEach(tuple, action, SizeT<std::tuple_size<TupleType>::value>()); 
} 

template < typename TupleType, typename ActionType > 
inline void TupleForEach(TupleType& tuple, ActionType action, SizeT<0>) { } 

template < typename TupleType, typename ActionType, size_t N > 
inline void TupleForEach(TupleType& tuple, ActionType action, SizeT<N>) 
{ 
    TupleForEach(tuple, action, SizeT<N-1>()); 
    action(std::get<N-1>(tuple)); 
} 

std::tuple<char, int, double> tt; 
TupleForEach(tt, (boost::lambda::_1 = 5)); 
+1

"より良い"の条件は何ですか? – Casey

+0

@Casey - 'std'または' boost'のライブラリ実装。そうでない場合は、コードが少ない実装です。この実装に問題があるかもしれません。 – Vahagn

答えて

1

いくつかのprevious, related questionでの回答(と自分自身を提供する1つ)があるにもかかわらず、私の最初の印象は、必要がにわたり反復するということですタプルは、貧弱な設計の反映である可能性があります。 std::tupleContainer conceptを満たしていないため、

ご存知のように、我々は、標準C++アルゴリズムを使用してstd::tupleを反復することができない理由があります。そして、正確には、std::tupleにはvalue_type(これらは異種)がないため、そのような概念を満たしません。独自の多型を作成し、それを標準コンテナ(たとえばstd::vector<std::shared_ptr<BaseClass>>)に格納したくないので、タプルを使用したことがわかりました。これはあなたにすばやい利益をもたらしました。しかしそれはまた、あなたが自発的にContainerの利点をあきらめたことを意味します。

これはうまくいくかもしれませんが、何とか強制的かつ不自然な感じがします。コンテナの意味が必要な場合は、コンテナを使用しないでください。多相セマンティクスが必要な場合は、なぜ多相タイプを使用しないのですか?

恐らく私は誇張していますが、これは私の最初の印象です。

+0

タプルの型の多態性基底クラスを作成しなかった理由は、気まぐれではありません:)これらの型はサードパーティ製のものですから、それらを使用する人は必ずしも、それら。しかし、これらの型は共通の概念を共有しているため、それぞれに有効な操作がいくつかあるため、これらの型のオブジェクトを格納するユーザーは、そのオブジェクトに対してそのような操作を実行することができます。 – Vahagn

+4

さらに、 'char'、' int'、 'double'のタプルを考えてみましょう。またはいくつかのポインタのタプル。第1の場合には、例えば、タプルメンバをゼロに設定する有効な動作であり、第2のケースでは、タプルメンバを 'nullptr'に設定する有効な操作ですが、確かにC++ではすべての算術型の基本クラスやすべてのポインタ型の基本クラスを考えるのはナンセンスです。 – Vahagn

関連する問題