Boost logo

Boost Users :

Subject: Re: [Boost-users] How to use boost::function with boost::phoenix?
From: Jens Mueller (jens.k.mueller_at_[hidden])
Date: 2010-05-03 06:25:14


Joel de Guzman wrote:
> On 5/1/2010 5:18 PM, Jens Mueller wrote:
>> Hi,
>>
>> I'm trying out boost:phoenix. Until now I used boost::lambda. I have code
>> written using boost::lambda that returns a boost::function. E.g.
>>
>> boost::function<float(float)> flog() {
>> using namespace boost::lambda;
>> return bind(static_cast<float(*)(float)>(std::log), _1);
>> }
>>
>> And with boost::lambda I can reuse the boost::function like this
>>
>> boost::function<float(float)> func = -bind(flog(), _1);
>>
>> to build bigger blocks.
>>
>> But I cannot make it work with boost::phoenix.
>>
>> boost::function<float(float)> func = -bind(flog(), arg1);
>>
>> does not compile.
>>
>> How do I use a boost::function within phoenix? Or what do I need to return
>> instead of a boost::function to reuse it in phoenix? Basically I want to
>> build more complex functions out of simple ones which are returned by some
>> function to hide the internals of the function.
>> I'm using Boost version 1.41.0 and g++ (Debian 4.3.2-1.1) 4.3.2.
>
> It is a known deficiency with phoenix that it does not work well
> with boost::function the way you are doing it, due to result_of
> protocol incompatibility. This has been bugging me for some time
> now. Let me think about an easy fix. In the meantime, I suggest
> wrapping the boost function call in a generic phoenix::function.
> Please see this thread:
>
> http://tinyurl.com/232t7yk
>
> Such a wrapper should work any boost function if you make it generic.

I see. Thanks. Can I make the wrapper more generic than:

template<typename func>
struct boostWrapper {
    template <typename T>
    struct result { typedef typename func::result_type type; };

    // TODO
    // can't I use an reference here
    func f1;
    
    boostWrapper(func const& f1)
        : f1(f1) {}

    typename func::result_type operator()(typename func::arg1_type i) const {
        return f1(i);
    }
};

template<typename func>
boost::phoenix::function<boostWrapper<func> >
wrap(func const& f1)
{
    return boostWrapper<func>(f1);
}

Specifically: How do I handle general n-ary functions? And is it safe to
just store a const reference for the boost function?

Jens


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