2017-06-14 11 views
9

n個のタプルを構築する必要があります。これらのn型は、他のn型の値型です。パラメータパックから値型のタプルを定義する方法

#include <boost/hana.hpp> 

namespace hana = boost::hana; 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    hana::tuple<Types...> sets; 
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done? 
}; 

これは次のように意図されています:このクラスにはおそらく異なるタイプのコンテナのパラメータパックを渡します。クラスはこれらのコンテナをタプルsetsに入れます。クラスには、コンテナの数が渡されたタプルのフィールドcombinationもあります。しかし、要素の型は、異なるコンテナの値の型です。

クラスは、それに渡されたコンテナのデカルト積を遅れて作成し、現在の組み合わせをcombinationに格納することを意図しています。しかし、どのようにしてバリデーショナルな方法で実際にコンテナの値型に到達することができますか?

+0

すべての型に 'value_type'がありますか? – StoryTeller

+0

これは前提条件です。 –

+0

この怠惰なデカルト商品クラスを書くと、あなたがハナに戻すことができればすばらしいことでしょう。私は遅延ビューを追加しようとしています。 'cartesian_product'を遅延的に実装するのは良い考えです。 –

答えて

11

もちろん可能です。パック展開を適切に宣言するだけです。

hane::tuple<typename Types::value_type...> combination; 

typename指定子の必須の使用に注意してください。経験則は、パック名を単一のタイプとして扱うことです。スコープ解決演算子を使用して型にアクセスするように指定する必要があるため、同じ構文/意味制約が適用されます。その後、最後にパックの拡張をタックします。落語の正解(彼の答えをしてください受け入れる)に拡大

Live Example

#include <vector> 
#include <map> 
#include <tuple> 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    std::tuple<Types...> sets; 
    std::tuple<typename Types::value_type...> combination; 
}; 


int main() { 
    std::vector<int> i; 
    std::map<int, std::vector<int>> m; 

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>> 
     c(i, m); 

    return 0; 
} 
5

:私はそれが簡単に翻訳の面でそれらを実装することにより、このようなタイプの翻訳を視覚化するために見つける

メタたとえば、次のようになります。

#include <vector> 
#include <map> 
#include <tuple> 

namespace metafunction_impl 
{ 
    // meta function taking one type (T) and 'returning' one type. 
    // i.e. a unary metafunction 
    template<class T> struct get_value_type 
    { 
    using result = typename T::value_type; 
    }; 
} 

// provide clean interface to the metafunction 
template<class T> using GetValueType = typename metafunction_impl::get_value_type<T>::result; 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    std::tuple<Types...> sets; 

    // use my metafunction 
    std::tuple<GetValueType<Types>...> combination; 
}; 


int main() { 
    std::vector<int> i; 
    std::map<int, std::vector<int>> m; 

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>> 
     c(i, m); 

    return 0; 
} 
+0

これは、パックを単一のタイプの名前として想像する理由を強く視覚化したものです。私の親指のアプローチよりも優れています。 +1 – StoryTeller

関連する問題