From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-05-04 09:55:11
On Friday 04 May 2001 04:07 am, you wrote:
> > > When there's no op=(const Functor &), assignment to
> > > 0 will call op=(const assign0 *). Assignment to a
> > > functor/function will simply call the (non-explicit)
> > > templated constructor.
> > Ah, interesting. We'd pay for this usefulness in efficiency, however,
> > the extra copy would require another memory allocation and deallocation.
> > not sure the cost is worth it.
> Well, you could use reference counting :)
I think we've laid this battle to rest :).
> > The general feeling was that the "f = 0"
> > syntax was less obvious than "f.clear()" (even though it mimics function
> > pointer syntax better), so it would be tough to convince the general
> > that this change is worth it.
> Hmm, I would say if I can assign a function pointer, it is
> only natural that I can also assign 0. Additionally, since
> 'if (f)', or better 'if (f !=/== 0)' is possible, it again
> makes 'f = 0' an obvious possibility.
I completely disagree with this :)
The conversion to bool (const void*, const undeleteable*, whatever) should
be though of as: 'if f evaluates true, then f has some target it will execute
if you invoke f's function call operator' not 'f can be implicitly converted
to its function pointer'. boost::function deals with function objects, not
function pointers; function objects are copy constructible and invocable, and
function pointers are a refinement of function objects that are also
assignable and equality comparable. We need to look at the core concept that
boost::function handles - the function object - and not inject syntax for it
based on the properties of specific refinements of that concept (Jesse - same
argument goes for operator==).
I think that allowing 'f = 0' is saying that boost::function is a
conceptually a pointer (it isn't - a pointer would not have copy semantics).
If two boost::function objects end up eventually targetting the same code, it
is because the user has given it a "shallow" function object at some point.
Comparisons such as 'f == 0' say 'does f point to the zero location' and
assume we've narrowed all our concepts to the function pointer concept.
> Then to clear, everyone will understand what will happen
> when clear() is called. However, its counterpart: set() does
> not exist, which might be seen as not-really-consistent.
Yes, I know :) It's been mentioned several times and I consistently forget to
> Note that I'm not saying support for 'f = 0' is crucial, I'm
> just saying that IMO 'it's not obvious' is not a very strong
> > If assign0 is hidden in a detail namespace, user's know they've been
> > not to dig that far into Boost internals. Note that the same thing done
> > "nil" here is done for "ignore" in the tuple code.
> One should not repeat the errors of the past...
I'd be interested in why you think this, but this is the wrong thread for it.
> ...but seriously, 'nil' specifically for 'function' doesn't
> feel right. There's nothing 'function' about 'nil'. I mean,
> 'nil' on its own is not related to function (at least that
> is not how the user will see it). Having a general boost::nil
> in e.g. nil.hpp or whatever sounds (somewhat) better.
I think most of us would use NULL if it were truly available, but
unfortunately that isn't going to happen any time soon. So instead we use
'0', which is only really meaningful because we read it as NULL (or we came
from a C backround where typing is willy-nilly). One resolution for this is
to have a 'nil' that has its own specific type and a slightly different
meaning. Instead of NULL or 0 meaning 'pointing to nothing', nil would mean
'possessing no value' or 'possessing an unusable value'.
I'd advocate using 'nil' instead of 0 or NULL because it conveys more
information than 0 and is more portable than NULL. Additionally the
difference in meaning allows it to apply to a greater variety of situations.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk