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

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
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


Boost list run by bdawes at, gregod at, cpdaniel at, john at