Boost logo

Boost :

From: Ronald Garcia (garcia_at_[hidden])
Date: 2001-07-22 14:17:38


Douglas Gregor writes:

> > If we take
> > the analogy of a "pointer to functor", you're fighting with the difference
> > between:
> >
> > 1) functor * p;
> > 2) functor const * p;
> > 3) functor * const p;
> > 4) functor const * const p;
> >
> > your current semantics seem to have (=> meaning "is analogous to"):
> > functor => 1)
> > const functor => 4)
> >
> > while the proposed semantics seem to be:
> > functor => 1)
> > const functor => 3)

I made a few typos later on in what I wrote. To clarify:
1) functor can be reseated, calls 'operator()' on its referent.
2) functor can be reseated, calls 'operator() const' on its referent.
3) functor cannot be reseated, calls 'operator()' on its referent.
4) functor cannot be reseated, calls 'operator() const' on its referent.

>
> I was proposing just:
> functor => 1
>
> and an auxiliary function object could (at 'function'
> assignment/initialization time) decide if for a particular target function
> object instance, it should be
> functor => 3
>
I'm not quite sure what you mean by "auxiliary function object." Could
you perhaps suggest some syntax?

given the following:

struct ftor {
   void operator()();
   void operator()() const;
};

void my_func(const function<void>& f) { f(); }

what do you propose happens if I call my_func with a boost function
pointing to 'ftor? I'm under the impression that your proposal would
call 'operator()()', which was what I meant above in my statement of
your proposal.

I'm not sure I understand what you're saying here. Could you write
out a possible syntax for this?

> > One pertinent question is, is there a sensible use for a functor with
> > semantics 2) or 4). That is, does it make sense to have a functor

argh! I meant 3) or 4) here, but I think you got the idea. It makes
sense to have a boost.functon that cannot be reseated regardless of the
constness of the referent.

> changed. However, see the reason in my prior post why having parallel
> function/const_function won't (and probably can't) work.

quoted here:
>
> Perhaps. The one major difference between iterator/const_iterator and a
> function/const_function is that iterators have definitive "pointed-to" types,
> e.g., iterator to int and iterator to const int. The same does not quite
> apply to function, because it "points to" some dynamically-chosen type that
> always has an operator() const and may have an operator() as well. I think
> that because of this discrepancy the decision to call const or non-const
> shouldn't be up to the 'function' itself (i.e., function or const_function),

Just some thought...suppose you had an iterator it over a container of
functor base class objects with virtual 'operator()()'. If you call:
(*it)();
it would call the derived object's operator()(). if you have a
"const iterator" (NOT const_iterator), the same thing would happen.
The difference is that the iterator cannot be moved. This const
iterator would be analogous to a "const boost.function" which could
not be reseated.

Now if you have a "const_iterator" cit into this container and call:
(*cit)();
it would call the derived's 'operator()() const'. Of course an iterator
of type "const const_iterator" would do the same, but not be movable.
Supposing there were a boost.const_function, this would be the
analogous type (if const, can't be reseated).

now, on to your discussion below:
>
> The conversions may even be impossible :). Thinking about this, for instance,
> with the above my_function_object class:
>
> boost::function<int, int, int> f = my_function_object();
> boost::const_function<int, int, int> fc = f;
>
> So "f" should call my_function_object::operator() and fc should call
> my_function_object::operator() const? Can't happen: f doesn't even know
> my_function_object::operator() const exists, because it only references the
> non-const version, so what actually happens is that fc targets a copy of f,
> which targets the non-const my_function_object::operator()!
>

I don't think that the above line should cause fc to target f as it
would a function object of any other type.
const_function would not target function, but cause a conversion from
type function to type const_function. This is an altogether different
beast. Now, the big question is as follows: Is it possible to detect
during a conversion from function to const_function (either at compile
or runtime) whether the referent of an already created boost.function
has an 'operator() const'.

take the following code:
---<snip>---
struct my_functor {
  void operator()() { } // no const
};

int main() {
// ...
my_functor* f = new my_functor();
my_functor const* fc = f;

 (*f)();
 (*fc)();
 return 0;
}
---<snip>---

A compiler should not accept it. I like to think that the same sort
of detection can be made in a conversion from boost.function to
boost.const_function, but due to casting stuffs, perhaps it cannot be
determined until runtime (I only vaguely understand the implementation
of boost.function)? At which point a runtime fault of some sort
sort could occur.

>
> > As far as making the semantic change, I vote for doing so. While
> > Boost.Function is already "out there", I think that the current
> > semantics confusing. If/When these changes are released, A notice
> > should go in the Boost Release notes stressing such a semantic
> > change.
> >
> >
> > ron
>
> Does Boost have Release Notes?
>
> Doug
I was thinking of what appears on the main web page after a release.


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