Boost logo

Boost :

Subject: Re: [boost] Local and Phoenix idiosyncrasy
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-26 18:44:08


On Sat, Nov 26, 2011 at 7:28 AM, Lorenzo Caminiti <lorcaminiti_at_[hidden]> wrote:
> // TODO: Is there a better way to do this? Ideally, I'd want the result type to
> // be the X template parameter without introducing the extra R...
> template<typename R>
> struct global_add {
>    typedef R result_type;
>
>    template<typename X, typename Offset>
>    R operator()(X x, Offset offset) const {
>        X total = x + offset;
>        std::cout << total << std::endl;
>        return total;
>    }
> };

I found out that the Phoenix docs show a better way to do this without
the extra template parameter R:
http://www.boost.org/doc/libs/1_48_0/libs/phoenix/example/factorial.cpp

struct factorial_impl {
    template <typename Sig> struct result;
    template<typename This, typename Arg>
    struct result<This(Arg)>
        : result<This(Arg const &)>
    {};
    template<typename This, typename Arg>
    struct result<This(Arg &)> { typedef Arg type; };

    template <typename Arg>
    Arg operator()(Arg const& n) const {
        return (n <= 0) ? 1 : n * (*this)(n-1);
    }
};

BTW, I have experimented a bit and I _think_ macros like the ones
below can be written to automatically generate the code above:

 // some global scope
 template<typename Arg1>
 Arg1 BOOST_PHOENIX_FUNCTION_TPL(Arg1 const& n) {
     return (n <= 0) ? 1 : n * (*this)(n - 1);
 } BOOST_PHOENIX_FUNCTION_END(factorial_impl);

These macros can only be used at non-local scope and the resulting
functor is of course polymorphic.

Would this be useful? I think Thomas tried something similar before:

On Sun, Nov 20, 2011 at 11:16 PM, Thomas Heller
<thom.heller_at_[hidden]> wrote:
> TBH, I considered writing macros to reduce the boilerplate of
> creating such construct for Phoenix. I decided to stop investigating that
> because at the end of the day, the macros grew in complexity and actually
> writing the boilerplate yourself turned out to be clearer, shorter and more
> flexible.

(The non-macro approach will always remain more flexible because users
are in full control-- they can add state to the struct (being careful
about expensive copies), etc.)

For the moment the BOOST_PHOENIX_FUNCTION_TPL macro I was able to
draft requires the template parameters to use the predefined names
Arg1, Arg2, ..., ArgN plus it assumes that the number of template
parameters equals the arity of the tuple specified to the macro unless
you do BOOST_PHOENIX_FUNCTION_TPL(1, Arg1 x, Arg1 y) which specifies
there's only 1 template parameter Arg1 even if there are 2 arguments x
and y. If there was interest in these macros, I could try to relax
these assumptions.

--Lorenzo


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