本文介绍了c ++ 03:使用boost的可变参数模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到一种解决方法,以在c ++ 03中使用可变参数模板.

I'm trying to find a workaround to use variadic templates within c++03.

我想实现的是-在模板化类中-实例化了boost::tuple属性,该属性将由每个单个类模板参数的向量组成.

What I would like to achieve is - within a templated class - instanciated a boost::tuple attribute, which would be composed of a vector for each single class template parameter.

这是使用c ++ 11可变参数模板的样子:

This is how it would look like using c++11 variadic templates:

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

   Vectors_t _vectorsTuple;
}

我想使用boost :: tuple和boost :: mpl或其他任何可能的方法来实现相同的目的.

I would like to achieve the same using boost::tuple and boost::mpl or whatever other possible ways.

谢谢

更新

这是我想出的最终解决方案.部分基于@stefanmoosbrugger命题.

This is the final solution I came up with.Partly based on @stefanmoosbrugger proposition.

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

推荐答案

这里是某种解决方法.我承认它看起来很丑陋.但是我认为这至少是获得某种变奏风格的一种方式:

Here is some kind of workaround. I admit that it looks totally ugly. But I think this is at least a way to get some kind of variadic style:

#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正在使用mpl::vector<T1,...,Tn>并将其转换为boost::tuple< std::vector<T1>, ..., std::vector<Tn> >.

What it does is: There is a macro that supports the variadic arguments. This macro passes the args to an mpl::vector. The FooHelper is taking the mpl::vector<T1,...,Tn> and converts it to a boost::tuple< std::vector<T1>, ..., std::vector<Tn> >.

好吧,我想这不是您想要的,但是也许您可以以某种方式使用它.由于代码块大,我把它作为答案而不是注释.

Well, I guess this is not what you want, but maybe you can use it somehow. I put it as answer and not as comment because of the large code block.

更新:如果您不喜欢Boost预处理器的内容,则可以使用Boost融合矢量获得相同的结果.引用增强文档中的内容:The tuple is more or less a synonym for fusion's vector..

UPDATE: If you don't like the boost preprocessor stuff you can get the same result with a boost fusion vector. Quote from the boost doc: 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;
}

这篇关于c ++ 03:使用boost的可变参数模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 11:21