Boost logo

Boost :

From: Doug Gregor (gregod_at_[hidden])
Date: 2001-02-13 13:20:55


On Tuesday 13 February 2001 08:36, you wrote:
> > ----- Original Message -----
> From: "Doug Gregor" <gregod_at_[hidden]>
> To: <boost_at_[hidden]>
> Sent: Sunday, January 21, 2001 8:10 AM
> Subject: [boost] any_function ("Callback" library)
>
> > I've tested it on MSVC++ 6.0sp4 and GCC 2.95.2. The only difference is in
> > initialization:
> >
> > any_function<int, int, int> f1 = plus<int>(); // 1
> > any_function<int, int, int> f2 (plus<int>()); // 2
> >
> > VC++ can handle 2 but not 1; GCC can handle 1 but not 2 :)
>
> Here are a few of my observations on any_function lib.
> *Isn't VC++ is right in rejecting 1 (given that the constructor has the
> explict keyword)

Yes, VC++ is correct. Unfortunately, GCC has a known parsing problem with #2
that has an ugly workaround:
any_function<int, int, int> f2 ((0,plus<int>())); // 3

The GCC snapshots have been fixed to some extent: #1 no longer compiles, but
neither does #2.

> *Copy Constructor (atleast in VC++ ) is never called :the templated
> function is called instead
> for example
> typedef any_function<int, int, int> tf1;
> tf1 f1(plus<int>()); //4
> tf1 f1_1(f1); //5
> 5 calls the tenplated constructor and not tf1::tf1(const tf1&)
> *also for assignment operator the templated cousin is called instead of
> tf1::operator=(const tf1&)

Interesting. I found that MSVC was calling the copy constructor in #5, but
the analagous operator= was not being used, i.e,:
tf1 f1_2;
// ...
f1_2 = f1; // 6

Does not call tf1::operator=(const tf1&), as you found out.

> To make 5 work, we could do something similar to what was done in
> the class boost::any.
> A MSVC_INCLUDE(template<>) could be added to the copy constructor.
> and the assigment operator
> But, VC++ also requires that we change the argument in
> template<typename Functor>
> explicit any_function(Functor f)
>
> to
>
> template<typename Functor>
> explicit any_function(const Functor& f)
>
> and
> template<typename Functor>
> any_function& operator=(Functor f)
>
> to
>
> template<typename Functor>
> any_function& operator=(const Functor& f)
>
> Is this change acceptable?.

When I tried this, it wreaked havoc when initializing any_function with a
free function because Functor is bound to a function and is_pointer<Functor>
dies. The same problem occurs when assigning to an any_function from a free
function.

The workaround is to add another function to do the actual copy of the
incoming functor/function:

template<typename Functor>
void assign_to(Functor f)
{
// ...
}

and just call it directly from the constructor/operator=. This relies on the
required conversion from function to function pointer, and almost works :).

It works fine for operator=. However, I get errors for the constructor
because it decides to bind Functor to a function reference in assign_to()
instead of binding it to a function pointer. The fix here is to use the
signature:
template<typename Functor>
explicit any_function(const Functor) { /* ... */ }

Thank you for the change. MSVC now uses the correct copy constructor and
assignment operator. There's an updated version at
http://groups.yahoo.com/group/boost/files/Callback/any_func-02-13.zip

        Doug


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