Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-11-15 15:35:45


On Thursday 15 November 2001 12:08 pm, you wrote:
> Let me see if I understand you correctly. You are saying that operator+=
> (and all other operators) should explicitly check for ref() and wrap it in
> an appropriate argument-ignoring function object.

Yes.

> A possible approach. What are its advantages?

1) Allows the capabilities we would want from "fref(x)" to be part of ref(x),
so, e.g., we could have:
  std::find_if(v.begin(), v.end(), ref(stateful_function_object));
  
  This is more consistent for the user than having ref(x) for normal objects
x and fref(x) for function objects... what happens in generic code when you
don't know if you have a function object or a normal object?

2) ref(x) would have semantics that make sense when not considering the
implementation of the Lambda library. Does ref(x)(5, 3.13159) returning x
really make sense if you don't know the implementation details of Lambda or
Bind?

3) Bind/Lambda can just wrap ref(x) in their own internal ref-like classes to
allow parameters to be ignored.

I'm looking at "ref(x)" as essentially a directive that says "use a reference
to x instead of copying it". Bind and Lambda have a particular view of how
this should be done (by making it a function object that ignores its
arguments), Function will have a different view of how this should be done
(by storing a pointer to the underlying function object without any cloning),
and standard algorithms would have yet a different view of how this should be
done (the ref object acts as a pass-through function object to allow stateful
function objects).

> This doesn't really fit the current Lambda (and Bind) spirit. Since the
> argument list is not specified,
[snip]
> So lambda expressions don't have arity. They act on arbitrary argument
> tuples. That's why ref(x) can take any arguments.

That strikes me as wrong from a theoretical standpoint. Say I have some
pseudo-C++ code:

struct negate {
  template<typename T> typeof(-T()) operator()(const T&) { return -T; }
};

Now if I have an object "op" of type negate, and I have the Lambda object
-_1, it seems wrong that op(a, b) is ill-formed whereas (-_1)(a, b) is -a. We
shouldn't lose the arity constraint just because we're using Lambda.

> Note that I don't have a vested interest in this matter; I'm simply trying
> to keep ref/bind compatible with LL hoping that people will painlessly
> transition to LL when its time comes.

I'd also like LL to integrate smoothly when it's ready, but I think ref(x) is
a great directive to use and I'd rather not see its scope limited by any
library.

        Doug


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