|
Boost : |
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-12-07 03:06:58
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk