MPL: Instantiating a template across permutations of types

Hello. I am trying to instantiate a template taking two parameters across a series of types contained in mpl::vector's, and place the resulting types in an mpl::vector. template <class A, class B> class T {}; typedef mpl::vector<int, double, char> Atypes; typedef mpl::vector<double, std::string> Btypes; template <template <class, class> class TEMPLATE, class ATYPE, class BTYPES, class CLASSES> struct unary_fold_inner : mpl::fold< BTYPES, CLASSES, mpl::push_back<mpl::_1, TEMPLATE<ATYPE, mpl::_2> >
{};
template <template <class, class> class TEMPLATE, class ATYPES, class BTYPES> struct unary_fold : mpl::fold< ATYPES, mpl::vector<>, typename detail::unary_fold_inner<TEMPLATE, mpl::_2, BTYPES, mpl::_1>::type
{};
typedef unary_fold< T, Atypes, Btypes
::type CLASSES;
I expect CLASSES will be an mpl::vector containing 2x3=6 types as follows: T<int, double> T<int, std::string> T<double, double> T<double, std::string> T<char, double> T<char, std::string> in other words, instantiating template T across all permutations of Atypes and Btypes. What I see instead is puzzling. Classes is indeed an mpl::vector, and indeed contains 6 types, but the types are simply: T<double, double> T<std::string, std::string> T<double, double> T<std::string, std::string> T<double, double> T<std::string, std::string> The iteration I'm trying to accomplish is all wrong. I think it has to do with how I'm creating my metafunctions. I'm still unclear about when the ::type suffix is needed (for the last parameter to mpl::fold<> for example) and whether I need an "apply" template somewhere in my struct's. Any help appreciated. v

AMDG cp now wrote:
Hello.
I am trying to instantiate a template taking two parameters across a series of types contained in mpl::vector's, and place the resulting types in an mpl::vector.
template <class A, class B> class T {}; typedef mpl::vector<int, double, char> Atypes; typedef mpl::vector<double, std::string> Btypes;
template <template <class, class> class TEMPLATE, class ATYPE, class BTYPES, class CLASSES> struct unary_fold_inner : mpl::fold< BTYPES, CLASSES, mpl::push_back<mpl::_1, TEMPLATE<ATYPE, mpl::_2> >
{};
template <template <class, class> class TEMPLATE, class ATYPES, class BTYPES> struct unary_fold : mpl::fold< ATYPES, mpl::vector<>, typename detail::unary_fold_inner<TEMPLATE, mpl::_2, BTYPES, mpl::_1>::type
{};
Problem #1. This causes the metafunction unary_inner_fold to be evaluated immediately. Don't put ::type here. You want unary_inner_fold to be evaluated by mpl::fold. Problem #2 MPL Lambda can't handle template template arguments. Use a metafunction class instead.
typedef unary_fold< T, Atypes, Btypes
::type CLASSES;
The following gives the correct answers for me: #include <string> #include <boost/mpl/vector.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/apply.hpp> #include <boost/mpl/quote.hpp> namespace mpl = boost::mpl; template <class A, class B> class T {}; typedef mpl::vector<int, double, char> Atypes; typedef mpl::vector<double, std::string> Btypes; template <class TEMPLATE, class ATYPE, class BTYPES, class CLASSES> struct unary_fold_inner : mpl::fold< BTYPES, CLASSES, mpl::push_back<mpl::_1, mpl::apply2<TEMPLATE, ATYPE, mpl::_2> >
{};
template <class TEMPLATE, class ATYPES, class BTYPES> struct unary_fold : mpl::fold< ATYPES, mpl::vector<>, typename unary_fold_inner<TEMPLATE, mpl::_2, BTYPES, mpl::_1>
{};
//typedef CLASSES; template<class Message> struct print {}; typedef print< unary_fold< mpl::quote2<T>, Atypes, Btypes >::type
::type CLASSES;
In Christ, Steven Watanabe

On Jan 22, 2008 5:36 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
cp now wrote:
Hello.
I am trying to instantiate a template taking two parameters across a series of types contained in mpl::vector's, and place the resulting types in an mpl::vector.
template <class A, class B> class T {}; typedef mpl::vector<int, double, char> Atypes; typedef mpl::vector<double, std::string> Btypes;
template <template <class, class> class TEMPLATE, class ATYPE, class BTYPES, class CLASSES> struct unary_fold_inner : mpl::fold< BTYPES, CLASSES, mpl::push_back<mpl::_1, TEMPLATE<ATYPE, mpl::_2> >
{};
template <template <class, class> class TEMPLATE, class ATYPES, class BTYPES> struct unary_fold : mpl::fold< ATYPES, mpl::vector<>, typename detail::unary_fold_inner<TEMPLATE, mpl::_2, BTYPES, mpl::_1>::type
{};
Problem #1. This causes the metafunction unary_inner_fold to be evaluated immediately. Don't put ::type here. You want unary_inner_fold to be evaluated by mpl::fold.
Problem #2 MPL Lambda can't handle template template arguments. Use a metafunction class instead.
typedef unary_fold< T, Atypes, Btypes
::type CLASSES;
The following gives the correct answers for me:
#include <string>
#include <boost/mpl/vector.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/apply.hpp> #include <boost/mpl/quote.hpp>
namespace mpl = boost::mpl;
template <class A, class B> class T {}; typedef mpl::vector<int, double, char> Atypes; typedef mpl::vector<double, std::string> Btypes;
template <class TEMPLATE, class ATYPE, class BTYPES, class CLASSES> struct unary_fold_inner : mpl::fold< BTYPES, CLASSES, mpl::push_back<mpl::_1, mpl::apply2<TEMPLATE, ATYPE, mpl::_2> >
{};
template <class TEMPLATE, class ATYPES, class BTYPES> struct unary_fold : mpl::fold< ATYPES, mpl::vector<>, typename unary_fold_inner<TEMPLATE, mpl::_2, BTYPES, mpl::_1>
{};
//typedef CLASSES;
template<class Message> struct print {};
typedef print< unary_fold< mpl::quote2<T>, Atypes, Btypes
::type ::type CLASSES;
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks a ton. Once I saw it the apply made much more sense. -v
participants (2)
-
cp now
-
Steven Watanabe