Boost logo

Boost Users :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2005-03-13 02:27:12


Bruno Martínez Aguerre writes:
> Hi,

Hi Bruno,

First of all, sorry for the late reply on this.

> I'm *partially* answering to myself.
>
> On Thu, 03 Mar 2005 22:54:56 -0200, Bruno Martínez Aguerre
> <br1_at_[hidden]> wrote:
>
> > I'm stuck at exercise 3-6 of the book. I have to write twice (see
> > below) as a lambda expression. I don't understand why the same
> > transformation that works for quasi fails for twice. Any help, please?
> >

[...]

> >
> > template <class F, class A>
> > struct twice : apply<F, typename apply<F, A>::type > {};
> >
> > BOOST_MPL_ASSERT(( is_same<twice<add_pointer<_1>,int>::type, int**> ));
> >
> > template <class F, class A>
> > struct quasi : plus<F, typename plus<F, A>::type > {};
> >
> > BOOST_MPL_ASSERT(( equal_to<quasi<int_<2>,int_<3> >, int_<7> > ));
>
> This works because quasi inherits from plus that inherits from int_.

Yep.

>
> > template <class F, class A>
> > struct quasi2 : apply<plus<_1, plus<_1,_2> >, F, A >::type {};
>
> Here ::type makes quasi2 inherit from int_, too, ...
>
> > BOOST_MPL_ASSERT(( equal_to<quasi2<int_<2>,int_<3> >, int_<7> > ));
>
> ... so this works again.
>
> > template <class F, class A>
> > struct twice2 : apply<apply<_1, apply<_1,_2> >, F, A >::type {};
> >
> > BOOST_MPL_ASSERT(( is_same<twice2<add_pointer<_1>,int>::type, int**> ));
>
> This has a number of bugs from copying quasi2. Something that works would
> be:
>
> template <class F, class A>
> struct twice2 : apply< apply1<_1, apply1<_1, _2> >, F, A > {};
>
> BOOST_MPL_ASSERT(( is_same<twice2<add_pointer<_1>,int>::type, int**> ));
>
> Now, this isn't right yet. If I replace apply1 with apply, it breaks.
> Could anybody point out why?

That's a subtle pitfall that at very least should be explicitly mentioned
in the documentation. I've put it on my TODO list; sorry you've had to
struggle with it!

In essence, the problem here is that variadic (unnumbered) 'apply' form
is never a valid placeholder expression because it always has
BOOST_MPL_LIMIT_METAFUNCTION_ARITY + 1 number of template parameters
(metafunction to invoke + maximum number of arguments), which is in conflict
with the Placeholder Expression concept's requirements --
http://www.boost.org/libs/mpl/doc/refmanual/placeholder-expression.html.

When I first realized this, I was thinking about bumping up
BOOST_MPL_LIMIT_METAFUNCTION_ARITY internally, so that, in fact,
the maximum supported arity of placeholder expressions (but not everything
else) would be BOOST_MPL_LIMIT_METAFUNCTION_ARITY + 1, but unfortunately
never got to it. I'll consider fixing this for 1.33.

Thanks for your feedback,

--
Aleksey Gurtovoy
MetaCommunications Engineering

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net