2016-11-18 201 views
1

我試圖找到一種解決方法來使用C++ 03中的可變參數模板。C++ 03:使用boost的可變參數模板

我想實現的是 - 在模板類中 - 實例化一個boost::tuple屬性,該屬性由每個單個類模板參數的向量組成。

這是它會是什麼樣子用C++ 11個可變參數模板:

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

    Vectors_t _vectorsTuple; 
} 

我想達到同樣的使用boost ::元組和boost :: MPL或任何其他可能的方式。

感謝

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; 
} 

它所做的是:有支持可變參數的宏。該宏將參數傳遞給mpl::vectorFooHelper採取mpl::vector<T1,...,Tn>並將其轉換爲boost::tuple< std::vector<T1>, ..., std::vector<Tn> >

嗯,我想這不是你想要的,但也許你可以以某種方式使用它。我把它作爲答案,而不是作爲評論,因爲大碼塊。

更新:如果你不喜歡升壓預處理器的東西,你可以得到與升壓融合向量相同的結果。引自升壓文檔: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 :: vector到實際元組的變換可能不那麼難看嗎? 我們真的需要BOOST_PP_ENUM宏和自定義push_front嗎? 想知道如果可以使用mpl :: transform而不是摺疊 – codeJack

+0

以更平滑的方式實現,則可以使用'mpl_vec_t'上的'mpl :: transform'將元素從'Tx'轉換爲'std :: vector '然後創建一個boost融合向量('boost :: fusion :: result_of :: as_vector :: type').. :)肯定看起來不那麼難看。 –

+0

您能否使用此解決方案更新您的代碼? :) – codeJack

相關問題