Boost logo

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