|
Boost : |
From: Marco Costalba (mcostalba_at_[hidden])
Date: 2008-05-16 14:27:33
On Fri, May 16, 2008 at 5:04 PM, Mathias Gaunard
<mathias.gaunard_at_[hidden]> wrote:
> Marco Costalba wrote:
>> Hi all,
>>
>> this is the first official version of multi-signature
>> boost::function extension (MSF) pushed to Boost Vault under the name
>> msf-1.0.zip
>
> Personally, I always thought getting a function objet per signature was
> a bad idea.
> Just take a single one with multiple overloads. Basically what you do
> with set_polymorphic_object, except you don't store it N times but only
> once.
>
Well, I'm changing again the API (yes I know it's painful, but this
time is the last one, I promise).
I would like to use operator=() also for polymorphic function objects
and deal the single copy issue as presented by Giovanni with a class
policy.
I explain better with the example stripped from the new test.cpp now
just in my private trunk, btw it works!
struct poly_t
{
int call_cnt;
poly_t() : call_cnt(0) {}
template<class T> T operator()(T t) { call_cnt++; return t; }
};
.......strip.....
/* In case the assigned object is a polymorphic function object
* then all the internal boost::functions are bounded in one go
*/
poly_t poly_obj;
msf::function<boost::mpl::vector<char(char), string(string)> > fp(poly_obj);
assert( fp('x') == 'x' );
assert( fp("hello") == "hello" );
assert( fp("hello") == "hello" );
/* By default boost::function makes a copy of the functor, so
* we end up with a different copy of poly_obj for each signature
* and the variable poly_obj::call_cnt is updated independently
* by the two calls. Below we retrieve the object wrapped by
* each of the two underlying boost::function and verify that
* poly_t::call_cnt is duplicated.
*/
assert( fp.get<char(char)>().target<poly_t>()->call_cnt == 1 );
assert( fp.get<string(string)>().target<poly_t>()->call_cnt == 2 );
/* In some cases it is expensive (or semantically incorrect) to
* clone a polymorphic function object. In such cases, it is possible
* to request to keep only a reference to the actual function object.
* This is done using the ref() function to wrap a reference to a
* polymorphic function object
*/
poly_t external_poly_obj;
fp = boost::ref(external_poly_obj);
external_poly_obj('x'); // note that we call this not through fp
external_poly_obj("hello");
assert( fp.get<char(char)>().target<poly_t>()->call_cnt == 2 );
assert( fp.get<string(string)>().target<poly_t>()->call_cnt == 2 );
/* A special case is when we need to have only a single copy of the
* polymorphic object for all the signatures. In this case we have to
* set to poly_single_copy the Tag template parameter of msf::function
* that normally defaults to poly_multi_copy
*/
poly_t* poly_obj_ptr = new poly_t();
msf::function<
boost::mpl::vector<char(char), string(string)>,
msf::poly_single_copy
>
fp_si(*poly_obj_ptr); // work both as c'tor argument...
fp_si = *poly_obj_ptr; //... and as assignment
delete poly_obj_ptr; // delete now, a copy has already been made
assert( fp_si('x') == 'x' );
assert( fp_si("hello") == "hello" );
assert( fp_si("hello") == "hello" );
/* Only one poly_t::call_cnt shared across the signature's slots */
assert( fp_si.get<char(char)>().target<poly_t>()->call_cnt == 3 );
assert( fp_si.get<string(string)>().target<poly_t>()->call_cnt == 3 );
> You may also want to provide a (separate) generic tool to generate a
> single function object from multiple ones.
>
>
Please could you better explain this point with an example ? thanks ?
Thanks
Marco
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk