2016-11-18 7 views
1

私はC++ 03内で可変テンプレートを使用する回避策を見つけようとしています。C++ 03:boosterを使用したVariadicテンプレート

私が達成したいのは、テンプレート化されたクラス内では、boost::tuple属性がインスタンス化されています。この属性は、各単一クラスのテンプレートパラメータのベクトルで構成されます。

template<typename ...Parameters> 
class Foo 
{ 
    typedef std::tuple<std::vector<Parameters>...> Vectors_t; 

    Vectors_t _vectorsTuple; 
} 

私は同じ使用してブースト::タプルを達成し、MPL ::ブーストまたは何らかの他の可能な方法したいと思います:

は、これはC++ 11の可変引数テンプレートを使用してのようになります方法です。

おかげ

UPDATE

これは私が思い付いた最終的な解決策です。 一部は@stefanmoosbrugger命題に基づいています。

template<class TypesList> 
class FooImpl 
{ 
    typedef TypesList TypesList_t; 
    typedef typename boost::mpl::transform < 
     TypesList_t, 
     std::vector<boost::mpl::_1> 
     >::type VectorTypesList_t; 
    typedef typename boost::mpl::reverse_fold< 
     VectorTypesList_t, 
     boost::tuples::null_type, 
     boost::tuples::cons<boost::mpl::_2, boost::mpl::_1> 
     >::type VectorsTuple_t; 

    protected: 
     VectorsTuple_t _vectorsTuple; 
}; 

template<class Type1, 
     class Type2 = boost::mpl::na, 
     class Type3 = boost::mpl::na, 
     class Type4 = boost::mpl::na> /* Made it up to four possible types as an example */ 
class Foo : public FooImpl<boost::mpl::vector<Type1, Type2, Type3, Type4> >{}; 

答えて

2

いくつかの回避策があります。私はそれが完全に醜いと認めます。しかし、私は、これは、少なくとも可変引数のスタイルのいくつかの種類を取得する方法だと思います:

#include <boost/preprocessor/repetition/repeat.hpp> 
#include <boost/preprocessor/repetition/enum_params.hpp> 
#include <boost/preprocessor/repetition/enum_binary_params.hpp> 
#include <boost/preprocessor/arithmetic/inc.hpp> 
#include <boost/preprocessor/cat.hpp> 
#include <boost/preprocessor/facilities/intercept.hpp> 

#include <boost/tuple/tuple.hpp> 
#include <boost/mpl/vector.hpp> 
#include <boost/mpl/copy.hpp> 

#include <vector> 

#define Foo(...) FooHelper< boost::mpl::vector<__VA_ARGS__> > 

template<class T, class Tuple> 
struct tuple_push_front; 

template<class T, BOOST_PP_ENUM_PARAMS(10, class T)> 
struct tuple_push_front<T, boost::tuple<BOOST_PP_ENUM_PARAMS(10, T)> > { 
    typedef boost::tuple<T, BOOST_PP_ENUM_PARAMS(9, T)> type; 
}; 

template <typename MPLVec> 
struct FooHelper { 
    typedef MPLVec mpl_vec_t; 
    // generate a boost::tuple< std::vector<...>, ... > out of the mpl vector 
    typedef typename boost::mpl::fold<mpl_vec_t, 
     boost::tuple<>, 
     tuple_push_front<std::vector<boost::mpl::_2>, boost::mpl::_1> 
    >::type type; 
}; 

int main() { 
    Foo(int,float,char) test; 
} 

それは何:可変長引数をサポートするマクロがあります。このマクロはargsをmpl::vectorに渡します。 FooHelperはで、boost::tuple< std::vector<T1>, ..., std::vector<Tn> >に変換されています。

これはあなたが望むものではないと思いますが、何とかして使用することができます。大規模なコードブロックのために私は答えとしてコメントにしていません。

UPDATE:ブーストプリプロセッサのものが気に入らない場合は、ブーストフュージョンベクターで同じ結果を得ることができます。ブーストの文書からの引用:The tuple is more or less a synonym for fusion's vector.

#include <boost/fusion/container.hpp> 
#include <boost/fusion/sequence.hpp> 
#include <boost/mpl/int.hpp> 
#include <boost/mpl/vector.hpp> 

#include <vector> 

#define Foo(...) FooHelper< boost::mpl::vector<__VA_ARGS__> > 

template <typename T> 
struct make_vector { 
    typedef std::vector<T> type; 
}; 

template <typename MPLVec> 
struct FooHelper { 
    typedef MPLVec mpl_vec_t; 
    typedef typename boost::mpl::transform<mpl_vec_t, make_vector<boost::mpl::_1> >::type vector_types; 
    typedef typename boost::fusion::result_of::as_vector<vector_types>::type vectors_t; 
    vectors_t _vectorsTuple; 
}; 

int main() { 
    Foo(int, double, float) x; 
} 
+0

おかげで、それは実際のタプルにMPLから変換::ベクトルはあまり醜い可能性があまりにも悪い:) 任意のチャンスではないのか? 本当にBOOST_PP_ENUMマクロとカスタムpush_frontが必要ですか? – codeJack

+0

をフォールドするのではなく、mpl :: transformを使ってスムーズに実現できたら、 'mpl_vec_t'に' mpl :: transform'を使って要素を 'Tx'から' std :: vector に変換することができます'boost :: fusion :: result_of :: as_vector :: type').. :)からブースト融合ベクトルを作成するだけで、間違いなく醜く見えるはずです。 –

+0

このソリューションでコードを更新してください。 :) – codeJack

関連する問題