Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-09-18 19:11:06


On Tuesday 18 September 2001 06:29, you wrote:
> This program fails to compile with Metrowerks CodeWarrior 7.0 and the
> latest boost from cvs:
>
> #include <boost/function.hpp>
>
> namespace { void empty_function() { } }
>
> int main()
> {
> boost::function<void> f(empty_function);
> }
>
> It seems that I need to say &empty_function, not just empty_function. Is
> this an intentional features of Boost.Function? A bug in Boost.Function? A
> bug in the Metrowerks compiler or standard library?

It's a bug in Boost.Function that has thus far eluded me (on broken
compilers, at least - the fix for compliant compilers is easy), so I decided
that it would be better to disallow the construct on all compilers instead of
having it work on some and not on others (which would have made code using
the feature nonportable).

Here's the basic problem: all function and function object parameters to
Boost.Function go through a single templated constructor:

template<typename F> function(const F& f);

For a function object, this is good. For a function pointer, this is also
good: f is a reference to a const pointer to a function. For a function (as
in your example), this doesn't match so we get an error. The solution would
be to have:

template<typename F, typename OR, typename OT1, ..., typename OTN>
function(OR (*f)(OT1, OT2, ..., OTN);

But this requires partial ordering of function templates when a function
pointer is passed in, which breaks on a _lot_ of compilers.

The only solution I know of for sure is to change the original constructor to:

template<typename F> function(F f);

In this case, the initialization of f causes the function to decay into a
function pointer. Unfortunately, it costs us a copy for function objects,
which is IMHO an unacceptable inefficiency. At one point I used both these
ideas: the extra constructor for conforming compilers and the copying version
of broken compilers. However, I later decided against this because behavior
should be _exactly the same_ across compilers.

I think you might be stuck with the extra '&' for a while longer :(

        Doug


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