Boost logo

Boost :

From: Doug Gregor (gregod_at_[hidden])
Date: 2001-05-01 12:20:48

On Tuesday 01 May 2001 09:37, you wrote:
> From: "Doug Gregor" <gregod_at_[hidden]>
> > I see two options for making it const, each with its semantic problems:
> > 1) Just make function::operator() const, but constness won't be passed
> > through to underlying function objects, so we're dealing with a semantic
> grey
> > area.
> With undefined behavior, more or less, unless boost::function uses
> 'mutable' internally. However, in this case, when I bind a boost::function
> to a function object with both const and non-const operator(), it will
> never call the const version.

boost::function essentially does use 'mutable' internally, because the type
erasure done to remove virtual functions uses free function pointers. It
isn't undefined behavior, just surprising behavior to the user expecting to
get a const operator() called from a const boost::function.

> > 2) Have both a const and a non-const version, and pass an "is_const" flag
> so
> > that function objects will be invoked as const or non-const and the
> constness
> > will be passed through. However, this requires a const version of
> operator()
> > to be defined for any function object regardless of whether it is used or
> not.
> I think this is the least bad option. Most operator()'s are const, and in
> the case where the function object has _only_ a non-const operator(), a
> dummy const version (that throws an exception) will have to be added by the
> user.

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.

> > So here's your answer: I dislike both solutions, and could not come up
> with
> > another one very easily. I'm leaning toward #1 because guaranteeing
> constness
> > is impossible given the ability to link to free functions.
> I don't see why free functions present a problem; they are always const.

The argument is that boost::function is a generalization of a function
pointer, and functions are never cv-qualified so given a function pointer
that is a member of a class, it doesn't matter what the cv-qualifications of
"this" are when the function pointer is invoked.

You've swayed me back toward #2 again :)

        Doug Gregor

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