Boost logo

Boost Users :

Subject: Re: [Boost-users] [phoenix] v2 to v3 transition of extension mechanism
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2011-04-14 03:45:08


On Thu, Apr 14, 2011 at 8:26 AM, alfC <alfredo.correa_at_[hidden]> wrote:
> The code has a couple of comments on obscure points that I still don't
> understand. For example,
> 1) I tried to use decltype so to have the generic return type of the
> function but it didn't work.
See below.
> 2) Can the std (for std::cos) specification be omitted so a context
> dependent 'cos' in an arbitrary namesapce is called? (depending on the
> return type of the nested eval()? In such case the lazy cos can be
> used for other exotic implementations of eager cos, even in different
> namespace.

Maybe a good idea, maybe leading to tons of ambiguity errors.
Any opinions about that?

> 3) Does it worth to use enable_if to construct the lazy function to
> avoid name clashes and horrible errors?, i.e. such that lazy functions
> are called only on phoenix expressions

I don't think so ... the expression::cos<...>::make function will turn non
phoenix actors into phoenix actors. The intention is that the cos expression
generator function is truly generic. SFINAEing out certain types might
be impossible
even more when you want the cos function to be picked up by ADL.

> see the numbers below, in the following working code:
>
> #include<boost/phoenix/core.hpp>
> #include<cmath>
>
> BOOST_PHOENIX_DEFINE_EXPRESSION(
>    (boost)(phoenix)(cos)
>  , (meta_grammar)           // Arg
> )
>
> namespace boost { namespace phoenix
> {
>        struct cos_eval{
>                template<class Sig>  struct result;
>                template<class This, class Arg, class Cont>
>                struct result<This(Arg, Cont)>{
>                    typedef
>                        double //works, but not generic
>                        //decltype(std::cos(eval(Arg(), Cont()))) // (1) doesn't work, why?
>                        type;
>                };
<snip>
Ok, this doesn't work because you are trying to value initialize a reference.
A small workaround:

       namespace detail
       {
           template <typename T> T make();
       }

       // ...
               template<class Sig> struct result;
               template<class This, class Arg, class Cont>
               struct result<This(Arg, Cont)>{
                   typedef
                       decltype(cos(eval(detail::make<Arg>(),
detail::make<Cont>())))
                       type;
               };
      // ...

Regards,
Thomas


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