c++03:使用 boost 的可变参数模板
c++03 : Variadic templates using boost
我正试图找到一种在 c++03 中使用可变参数模板的解决方法。
我想要实现的是 - 在模板化 class 中 - 实例化 boost::tuple
属性,该属性由每个 class 模板参数的向量组成。
这是使用 c++11 可变参数模板的样子:
template<typename ...Parameters>
class Foo
{
typedef std::tuple<std::vector<Parameters>...> Vectors_t;
Vectors_t _vectorsTuple;
}
我想使用 boost::tuple 和 boost::mpl 或任何其他可能的方式实现相同的目的。
谢谢
更新
这是我想出的最终解决方案。
部分基于@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> >{};
这里有一些解决方法。我承认它看起来非常丑陋。但我认为这至少是一种获得某种可变样式的方法:
#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::vector
。 FooHelper
将 mpl::vector<T1,...,Tn>
转换为 boost::tuple< std::vector<T1>, ..., std::vector<Tn> >
。
好吧,我想这不是您想要的,但也许您可以以某种方式使用它。由于代码块较大,我把它作为答案而不是评论。
更新: 如果您不喜欢 boost 预处理器,您可以使用 boost 融合向量获得相同的结果。引自 boost 文档: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 中使用可变参数模板的解决方法。
我想要实现的是 - 在模板化 class 中 - 实例化 boost::tuple
属性,该属性由每个 class 模板参数的向量组成。
这是使用 c++11 可变参数模板的样子:
template<typename ...Parameters>
class Foo
{
typedef std::tuple<std::vector<Parameters>...> Vectors_t;
Vectors_t _vectorsTuple;
}
我想使用 boost::tuple 和 boost::mpl 或任何其他可能的方式实现相同的目的。
谢谢
更新
这是我想出的最终解决方案。 部分基于@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> >{};
这里有一些解决方法。我承认它看起来非常丑陋。但我认为这至少是一种获得某种可变样式的方法:
#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::vector
。 FooHelper
将 mpl::vector<T1,...,Tn>
转换为 boost::tuple< std::vector<T1>, ..., std::vector<Tn> >
。
好吧,我想这不是您想要的,但也许您可以以某种方式使用它。由于代码块较大,我把它作为答案而不是评论。
更新: 如果您不喜欢 boost 预处理器,您可以使用 boost 融合向量获得相同的结果。引自 boost 文档: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;
}