Using an mpl sepquence as a template parameter
Hi, I have class that takes an mpl sequence as its parameter like this: X<mpl::vector<A, B, C> > And I would like to be able to have the class be used without explicitly declaring the mpl sequence like this: X<A, B, C> I know this could be accomplished using variadic template parameters, but I am using an older compiler. I was wondering if there was a macro in boost to do this, such as: template<BOOST_MPL_VARIADIC_PARAM_PACK(T)> class X { typedef mpl::vector<BOOST_MPL_VARIADIC_PARAM_UNPACK(T)> type; }; If a macro is not available, does anyone know how I could write a macro like this? Or what is the default type used for mpl sequences when a type is unspecified? Thanks, Paul
[Sorry if this was sent twice, but it appears to me that I didn't actually hit "Send" the first time...] On Mon, Nov 14, 2011 at 12:26 PM, paul Fultz <pfultz2@yahoo.com> wrote:
Hi, I have class that takes an mpl sequence as its parameter like this: X<mpl::vector<A, B, C> > And I would like to be able to have the class be used without explicitly declaring the mpl sequence like this: X<A, B, C> I know this could be accomplished using variadic template parameters, but I am using an older compiler. I was wondering if there was a macro in boost to do this, such as: template<BOOST_MPL_VARIADIC_PARAM_PACK(T)> class X { typedef mpl::vector<BOOST_MPL_VARIADIC_PARAM_UNPACK(T)> type; }; If a macro is not available, does anyone know how I could write a macro like this? Or what is the default type used for mpl sequences when a type is unspecified?
I think there are a number of ways to do this. One might be to take advantage of boost::mpl::na, though it looks like technically an implementation detail so its stability could be questionable (defined in <boost/mpl/aux_/na_fwd.hpp>, I believe). For example: template< class T0 = boost::mpl::na, class T1 = boost::mpl::na, class T2 = boost::mpl::na, [and so on...] > struct X { typedef boost::mpl::vector< T0, T1, T2, [and so on...] > type; }; You can use the Boost.Preprocessor library, e.g., BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_BINARY_PARAMS, to make this a lot less repetitious. - Jeff
Several times I've done something like this: namespace detail { struct none {}; template <typename TSeq> struct strip_none { typedef typename boost::mpl::remove<TSeq, none>::type type; }; } // namespace detail template < typename T0, typename T1 = detail::none, typename T2 = detail::none, typename T3 = detail::none, typename T4 = detail::none, typename T5 = detail::none, typename T6 = detail::none> class some_class { typedef boost::mpl::vector<T0, T1, T2, T3, T4, T5, T6> raw_types; typedef typename detail::strip_none<raw_types>::type types; ... }; Presumably some simple PP magic could make this prettier. -Gabe
Thanks for the help. After digging around, it seems I can define the two macros like this: #define MPL_VECTOR_PACK(x) BOOST_MPL_PP_DEFAULT_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, x, boost::mpl::na) #define MPL_VECTOR_UNPACK(x) BOOST_MPL_PP_PARAMS(BOOST_MPL_LIMIT_VECTOR_SIZE, x) Except as you say this uses an implementation detail. It would be nice if they added some macros like these in the future, to get semi support for varidiac parameters in older compilers.
I think there are a number of ways to do this. One might be to take advantage of boost::mpl::na, though it looks like technically an implementation >detail so its stability could be questionable (defined in <boost/mpl/aux_/na_fwd.hpp>, I believe). For example:
template< class T0 = boost::mpl::na, class T1 = boost::mpl::na, class T2 = boost::mpl::na, [and so on...] > struct X { typedef boost::mpl::vector< T0, T1, T2, [and so on...] > type; };
You can use the Boost.Preprocessor library, e.g., BOOST_PP_ENUM_PARAMS and BOOST_PP_ENUM_BINARY_PARAMS, to make this a lot >less repetitious.
- Jeff
participants (3)
-
Gabriel Redner
-
Jeffrey Lee Hellrung, Jr.
-
paul Fultz