David A. Greene wrote: > But consider this testcase: > > //#define CT_DEBUG > > //#include "ct_print.hh" > #include <boost/mpl/placeholder.hpp> > #include <boost/mpl/lambda.hpp> > > template<typename T, typename U, typename V> > struct my_type { > }; > > template<typename T, typename U, typename V> > struct my_type_generator { > typedef my_type<T, U, V> type; > }; > > template<template<typename, typename, typename> class Base, > typename T, typename U, typename V> > struct trivial_generator { > typedef Base<T, U, V> type; > }; > > int main(void) > { > typedef my_type_generator<char, short, int> generator; > //CT_PRINT(my_type_generator_result_is, generator::type); > > typedef trivial_generator<my_type, char, short, int> t_generator; > //CT_PRINT(trivial_generator_result_is, t_generator::type); > > // Try to make some generators > typedef boost::mpl::lambda<my_type_generator<char, boost::mpl::_1, > boost::mpl::_2> >::type lambda_generator; > typedef lambda_generator::apply<short, int> lg_apply_result; > //CT_PRINT(lambda_generator_result_is, lg_apply_result::type); > > // Does not work > typedef boost::mpl::lambda<trivial_generator<my_type, char, > boost::mpl::_1, boost::mpl::_2> >::type lambda_trivial_generator; > // g++ 3.2 claims apply doesn't exist. > typedef lambda_trivial_generator::apply<short, int> ltg_result; > //CT_PRINT(lambda_trivial_generator_result_is, ltg_result::type); > > return(0); > } >
That's because the MPL's lambda works only with metafunctions which template parameters are _types_, and only types: 1) a "canonical" metafunction, OK: template< typename T > struct identity { typedef T type; }; typedef lambda< identity<_> >::type f; BOOST_MPL_ASSERT_IS_SAME(f::apply<int>::type, int); 2) a metafunction with non-type template parameter, can't be used in lambda expressions: template< typename T, int i = 0 > struct identity { typedef T type; }; typedef lambda< identity<_> >::type f; BOOST_MPL_ASSERT_IS_SAME(f::apply<int>::type, int); // error! 3) a metafunction with template template parameter, can't be used in lambda expressions: template< typename T > struct something; template< typename T, template< typename > class F = something > struct identity { typedef T type; }; typedef lambda< identity<_> >::type f; BOOST_MPL_ASSERT_IS_SAME(f::apply<int>::type, int); // error! Strictly speaking, (2) and (3) are not even metafunctions in MPL's terminology. > > >>But I can construct a generic trivial generator: > >> > >>template<template<typename A, typename B, typename C> class Base, > >> typename T, typename U, typename V> > >>struct trivial_generator { > >> typedef Base<T, U, V> type; > >>}; > >> > >>Then I can use MPL lambda facilities. Unfortunately, I need a > >>trivial_generator for every arity of class template. > > > > Only as part of the implementation. You just need a nice > > wrapper over the top to hide it all. > > Right. Can you point me to the MPL equivalent as a guide of > how to do this? Actually, even ignoring the aforementioned lambda issue, it's not possible to write a single template (a wrapper or not) that would take template template parameters of different arity - if it were, the library itself would use the technique to implement the single 'quote/mem_fun' template instead of providing the family of 'mem_fun1', 'mem_fun2', etc. constructs. It _is_ possible to implement a single template along the lines of the SHAZAM template you've mentioned early in the thread: template<typename T, typename U, typename V> struct my_type { ... } // Note: no ::type member typedef SHAZAM<my_type<int, _1, _2> > generator; typedef generator::template apply<char, float>::type my_type_inst; but not at the user side - the library internal mechanisms needs to be made aware of it. I considered this before, - as well as the option of directly supporting the "reduced" metafunction form, - and the latter is currently my preference. Will see if something changes after I actually implement it (for one, it might slow down the lambda significantly, - but we'll see). Aleksey _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost