Boost logo

Boost :

From: gregod_at_[hidden]
Date: 2001-05-07 12:41:04


--- In boost_at_y..., "Geurt Vos" <G.Vos_at_r...> wrote:
>
> > >
> > > 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

I knew you'd notice that :). I've been planning on reworking the
documentation to stress that boost::function works on function
objects, and that function pointers are merely a singleton function
object that happens to have a more optimal representation inside
boost::function.

> 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> &);
>
>

I'm not sure I understand what you mean by this. It's a construction
if you pass in something other than a boost::function<void>, but so
what? I'm obviously missing something :)
 
> 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.

I disagree that we should remove the optimization. I think this is
solvable through documentation (as mentioned above).

> 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 :)

Obviously it's off-topic for the thread, but 'ignore' lets you do
something like:
int a, c;
tie(a, ignore, c) = make_tuple(1, 2, 3);

This assigns a=1 and c=3, but ignores the 2. It's useful when tuples
are used as return values and you want to ignore part of the value.
 
> > > ...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

This is probably something to bring into its own separate topic. Even
those interested in boost::function won't necessarily be reading 7
levels deep in the thread.

        Doug


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