2015-12-14 7 views
9

boost :: variantを "2次元の方法"で扱う方法を教えてください。奇妙に聞こえるが、私のコードは言わせてより多くの(たぶん):私が試したようboost :: variantを "2次元の方法"で使用して異種のstd :: mapを定義する方法

Parameter<si::length, double> SampleParameter1; 
Parameter<si::dimensionless, short> SampleParameter2; 

:上記で定義された私のパラメータの

template<typename PARAM_TYPE, typename DATA_TYPE=double> 
class Parameter : public quantity<PARAM_TYPE, DATA_TYPE> 
{ 
... 
} 

使用例:私はクラスと呼ばれるパラメータをコード化している

上記の例で説明すると、とdouble, short, intなどの異なるデータ型を使用していくつかのパラメータタイプを定義できます。

M上記のサンプルのようにParameterタイプのインスタンスを格納できるstd::mapコンテナを作成することです。

そこで私は宣言した:

typedef boost::variant<Parameter<si::dimensionless, short>, Parameter<si::length, double> > SupportedParameterTypes; 
std::map<int, SupportedParameterTypes> myMapStorage; 

これはかなりうまく動作しますが、1つの大きな欠点を持っている私が解決したい - 私は私のようにSupportedParameterTypesタイプでサポートしたいパラメータタイプのすべての単一の組み合わせを定義する必要があります上で定義した。

私の考えは、ブーストを定義することでした:: MPL ::ベクトルは、私がサポートしたいすべてのパラメータの種類をconstaining:

typedef boost::mpl::vector<si::dimensionless, si::length> ParameterTypes; 

、他方ではサポートされているすべての可能なパラメータのデータ型:

typedef boost::mpl::vector<short, int, float, double> ParameterDataTypes; 

私の悩みがあり来る:

typedef typename boost::make_variant_over<ParameterTypes>::type ParameterTypeVariants; 
typedef typename boost::make_variant_over<ParameterDataTypes>::type ParameterDataVariants; 

typedef boost::variant<Parameter<ParameterTypeVariants, ParameterDataVariants> > SupportedParameterTypes; 

しかしを定義します他のいくつかのboost::variantによってdefineedているもの(Parameter)のは動作しないようです:O(

QUESTION:どのように適切なboost::mpl::vector秒で定義されているすべての私のParameterタイプを保持std::mapコンテナを定義するには?

この問題を解決するためのお手伝いをさせていただきます。多分私が書いたようにそれをコード化することは誰にも分かりません。私の目標は、std :: mapによって柔軟な記憶域を持たせて、私のコードを曖昧にすることなくすべてのMy Parametersを保持できるようにすることです。ヘルプ

+0

SEPARなぜ2 'mpl'ベクトルとしてboost :: variant 、Parameter のようなシンプルなものよりも優れています。 > '? –

+0

2つのタイプを分離する必要がある理由は、どのタイプのパラメータも任意のデータタイプと組み合わせることができるからです。約20種類のsi ::タイプと約4種類のデータがあります。それは私が避けたいと思っている膨大な量の組み合わせを生むでしょう。とにかく、あなたの返事をありがとう! –

答えて

3

のための私の質問/リクエストへの応答を事前に

多くのおかげであなたが

template <typename Seq, typename T1, typename T2> 
struct cartesian_parameters_helper; 

template <std::size_t...Is, typename T1, typename T2> 
struct cartesian_parameters_helper<std::index_sequence<Is...>, T1, T2> 
{ 
    static constexpr std::size_t size1 = std::tuple_size<T1>::value; 
    using type = boost::variant< 
     Parameter< 
      std::tuple_element_t<Is/size1, T1>, 
      std::tuple_element_t<Is % size1, T2> 
      >...>; 
}; 

template <typename T1, typename T2> 
struct cartesian_parameters 
{ 
    using type = typename cartesian_parameters_helper< 
     std::make_index_sequence<std::tuple_size<T1>::value 
           * std::tuple_size<T2>::value>, 
     T1, T2>::type; 
}; 

ようなもので、すべてのあなたのペアを生成し、その後、使用することができますO):もちろんのスマートな解決策を探してそれ

using SupportedParameterTypes = 
    cartesian_parameters<std::tuple<si::dimensionless, si::length>, 
         std::tuple<short, int, float, double>>::type; 

Demo

+0

私はこの提案を使用して私のものを実装しようとしていますが、C++ 14固有のようです - 少なくとも私はstd :: index_sequence <>をC++ 11で有効にすることはできません。 C++ 11には類推がありますか?たとえばBoostライブラリでは?事前に多くの感謝... –

+0

SO上に 'index_sequence'と' make_index_sequence'の実装がいくつかあります。 – Jarod42

関連する問題