Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2003-01-12 02:44:07


Jaap Suter wrote:
> Hi,

Hi Jaap,

> I need some help with providing lambda support for my own
> meta functions. I think this has to do with the following thread:
>
> http://aspn.activestate.com/ASPN/Mail/Message/1387917
>
> but I can't really figure out what to do.

Have you seen this one -
http://lists.boost.org/MailArchives/boost/msg39533.php? That's pretty much
all there is to it.

>
> Basically, I have the following meta function (more
> complicated in real life, but the number of parameters is the same)
>
> template< class A, class B, class C >
> struct meta_fun : mpl::plus< A, B, C > {};
>
> And I use it as follows:
>
> template< class List, class Bar >
> struct foo
> {
> typedef typename mpl::fold<
> List,
> mpl::integral_c< size_t, 0 >,
> meta_fun< mpl::_1, mpl::_2, Bar >
> >::type type;
> }
>
> Perhaps it is interesting to note that only the first and
> second parameter of the meta function are lambda'd. The last
> parameter is 'fixed' to Bar. Is this at all possible with lambda,

Sure!

> or do I need to 'bind' the third parameter to create a
> meta-function that takes two parameters? It compiles on Intel
> and GCC, so I guess it is supported.

Everything that seems intuitive is supported :). If it doesn't work, it's
most probably a bug.

But the above example _does_ compile on every platform MPL supports -
including MSVC 6.5/7.0 (assuming the latest CVS sources). Or are you using
the 1.29.0 archive?

>
> In my actual code I'm not using mpl::plus but another meta-function
> that tries to acces A::value_type and B::value_type. This works
> fine on Intel and GCC, but MSVC gets the wrong types for A and B
> because it tells me that:
>
> error C2039: 'value_type' : is not a member of
> 'boost::mpl::arg<N>'
> with
> [
> N=2
> ]
>
> This is wrong because at the point where the error occurs I'm asking
> for the value_type member of something should be integral_c<> and not
> arg<>. I guess the fix lies in the BOOST_MPL_AUX_LAMBDA_SUPPORT and
> VOID_SPEC macros.

The former one is enough.

> But I don't really understand what these macros do (looking at their
definitions
> didn't really help either). I've tried something like:
>
> template< class A, class B, class C >
> struct meta_fun : mpl::plus< A, B, C >
> {
> BOOST_MPL_AUX_LAMBDA_SUPPORT( 3, meta_fun, (A, B, C) );
> };

That's exactly how a metafunction should be patched to become usable in
lambda expressions on deficient compilers (except for the semicolon at the
end of the macro).

> but that didn't fix it.

Hmm, works for me, even if I remove the 'plus' inheritance:

    template< class A, class B, class C >
    struct meta_fun
    {
        typedef A type;
        BOOST_MPL_AUX_LAMBDA_SUPPORT( 3, meta_fun, (A, B, C) )
    };

> I guess my question is: how would you define meta_fun so it supports
> lambda on MSVC 7?

I hope that all the above answers this question.

> Or if it's possible, do you have some time to give a short explanation
> on the LAMBDA macros,

    BOOST_MPL_AUX_LAMBDA_SUPPORT(arity, name, params)

    arity - metafunction's arity
    name - metafunction's name
    params - metafunction's formal template parameters, passed as PP tuple,
e.g. '(T1,T2,T3)'

> what compiler-problems they try to fix, and how they do it?
>

They are compensating the lack of partial template specialization or/and
template template parameters support by the means of introducing an
intrusive metafunction's introspection mechanism. The implementation details
are gloriously nasty, vary from compiler to compiler, and generally aren't
worth one's time.

> Any information will of course be updated in the Effective MPL wiki.

That would be very much appreciated!

Aleksey


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