Boost logo

Boost :

From: Doug Gregor (gregod_at_[hidden])
Date: 2001-05-02 10:40:30


On Wednesday 02 May 2001 09:05, you wrote:
[snip]
> >It strikes me as dangerous that we put off what is usually a compile-time
> >check for const-correctness until run-time. However, I see no other way
> > to get both const and non-const versions working properly: using
> >either virtual
> >functions or type erasure, both const and non-const must be instantiated,
> > so even if const is invalid for a specific function object something must
> >happen - but it has to be at run-time. Perhaps that is just the price of
> >flexibility.
>
> What about declaring but not defining, to turn it into a link-time error?
>
> --Beman

I think that type erasure precludes the possibility of detecting this problem
before run-time, because the erasure makes it impossible to pass compile-time
information through the barrier between the boost::function public interface
and the public interface of the target function/function object.

The barrier is clearly necessary to handle different target types (due to
different calling conventions, operator() overloads vs. calls through
function pointers, etc) because boost::function::operator() must invoke them
through the same interface (otherwise they would not be interchangeable at
run-time).

We can't pass compile-time information through this barrier because the
barrier is a run-time entity: it is created by a construction or call to the
assignment operator, and later used in the function call operator. Could we
have two barriers, one for const and one for non-const? We cannot, because
both barriers would have to be created in the assigment/constructor of the
boost::function, and therefore it would have to be valid to call through
either barrier.

I know of two ways to generate the barrier: virtual functions or functions
taking a void* / void (*)():
        - In the virtual functions case, it is undefined whether an implementation
implicitly instantiates virtual functions, so for instance we cannot have our
barrier be a class with a virtual operator() and a virtual operator() const
and have a failure at link-time.
        - In the functions taking void*/ void (*)() case (as currently implemented),
the address of the barrier function must be taken in the
assignment/construction of a boost::function, so it will be instantiated.
Then if, for instance, a function object target does not have a const
operator(), we will get a link-time failure regardless of whether or not the
const version of operator() is actually used.

Perhaps this is why the standard has both mem_fun and const_mem_fun?

        Doug


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