|
Boost : |
From: Geurt Vos (G.Vos_at_[hidden])
Date: 2001-05-07 02:52:18
> >
> > 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.
>
Although I can live with this description, the thing is that the
entire class is too much a pointer to think of it is not a pointer.
Hence the bool conversion _will_ be seen as comparing to a 0 pointer
constant. Moreover, from the docs I quote:
--- "The header <boost/function.hpp> provides several classes that are generalized function pointers" --- Generalized function pointers? And still you say one shouldn't think of it as a pointer? So my advice to this all: either give it full pointer semantics (don't!) or make it a functor only thing, with only a high level interface and lose the ability to assign function pointers. I wouldn't want to go for the first option, because there will be great many problems and all. For one the 0 assignment won't work correctly in the following case (because it's construction, not assignment): void SomeFunc(const boost::function<void> &); Even though there's some optimization for function pointers, I strongly urge this support is removed. For one free functions won't be used that often, and also, explain to the user that function assignment - something they'll barely use - is optimized, whereas member function assignment is not. Concluding, IMO the low-level interface should go and only a high level interface should remain: function(); function(functor) void set(functor) void clear(); bool empty() const; operator()(...) // I mean several, not the ellipsis! I'm uncertain whether op== should be implemented... > > 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 > > argument. > > > > > If assign0 is hidden in a detail namespace, user's know they've been warned > > > not to dig that far into Boost internals. Note that the same thing done for > > > "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. > Don't remove the '...but seriously' part from it. It's quite simple though, if I don't like 'nil' specifically for 'function', it's quite obvious I also don't like something as generic sounding as 'ignore' for something specific (tuple in this case). I don't know the details about this 'ignore' thing, so I might actually like 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. > Then why isn't there such a thing in boost?? It could be something like: struct nil_t { template <typename Type> operator Type *() const { return 0; } }; const nil_t nil = nil_t(); - 'nil' can be used with any pointer, but not with non-pointers (ints and floats) - it can be used as distinct type: function(nil_t = nil); Now to what it can't do: ...anyone? Geurt
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk