Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-12-12 17:52:47


Iain K.Hanson wrote:
> I'm having a problem using fold with the example from the reference
> page. I can get the following example from copy to comile as fold
>
> namespace mpl = boost::mpl;
> using mpl::_;
>
> typedef mpl::vector10_c<int,9,8,7,6,5,4,3,2,1,0> answer;
>
> typedef mpl::fold<
> mpl::range_c<int,0,10>
> , mpl::vector<>
> , mpl::push_front<_,_>
> >::type result;
>
> BOOST_STATIC_ASSERT(mpl::size<result>::value == 10);
> BOOST_STATIC_ASSERT((mpl::equal< result,answer >::type::value));
>
>
> but this won't:
>
>
> namespace mpl = boost::mpl;
> using mpl::_1;
> using mpl::_2;
>
> typedef
> mpl::vector<long,float,short,double,float,long,long double>
> types;
>
> typedef mpl::fold<
> types
> , mpl::integral_c<long, 0>
> , mpl::if_< boost::is_float<_2>, mpl::next<_1>,_1 >
> >::type number_of_floats;
>
> typedef mpl::lambda< number_of_floats >::type func;

Just a quibble - the above line is unnecessary.

>
> BOOST_STATIC_ASSERT(( number_of_floats::value == 3 ));
                                                      ^^^
An error in the docs, should be 4. Sorry!

>
> I presume that the problem is here
>
> , mpl::if_< boost::is_float<_2>, mpl::next<_1>,_1 >
> ^^^^^^^^^^^^^^^^^^^
>
> as this is a non-mpl metafunction.

Actually, it is! Try this one:

    typedef lambda< boost::is_float<_1> >::type is_float;
    typedef apply1< is_float, float >::type res;
    BOOST_STATIC_ASSERT(res::value == true);

> Can any one tell me how to fix the above please?

    BOOST_STATIC_ASSERT(number_of_floats::value == 4);

Fixed in the reference docs' sources, too.

>
> Also, what are the requirement on a metafunction to be used with
> lambda. A simple example would be useful.

On a conforming compiler, the simple form
(http://www.mywikinet.com/mpl/paper/mpl_paper.html#metafunctions.simple)

    template< typename T1, ..., typename Tn >
    struct f
    {
        typedef ... type;
    };

just works "out-of-box":

    template< typename T > struct identity
    {
        typedef T type;
    };

    typedef lambda< identity<_1> >::type f;
    typedef apply1< f, int >::type res;
    BOOST_MPL_ASSERT_IS_SAME(res, int);

HTH,
Aleksey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk