|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-02-19 08:46:01
Brian McNamara wrote:
[...]
> Dealing with references is relatively straightforward for first-order
> functoids, but when you deal with higher-order ones, it quickly
> becomes hard (impossible?) to do the right thing. For example:
> suppose we want to write a functoid "app", such that
>
> app( f, x ) == f(x)
>
> Should the second parameter be "by value" or "by reference"? The
> "right answer", IMO, is that it depends on whether "f" takes its
> argument by value or reference. Except that this dependency now
> excludes many uses of app(), such as
>
> app( _, 3 )
>
> Even though the result of that may be later used in a context that
> should/would be legal, "right now" we don't know if we should be
> copying the 3 or trying to take a reference to it. Whichever choice
> we make, it might turn out to be the "wrong" choice later.
Taking the liberty to reorder:
> That is, you cannot write "app" so that both calls here:
>
> int f(int);
> int g(int&);
> int x;
> ...
> app(_,3)(f);
> app(_,x)(g);
>
> work properly. It's impossible.
Let's see if I get this right:
#include <boost/bind.hpp>
#include <boost/bind/apply.hpp>
#include <iostream>
int f(int x)
{
std::cout << "f(" << x << ")\n";
return x;
}
int g(int & x)
{
std::cout << "g(" << x << ")\n";
return ++x;
}
int main()
{
int x = 2;
// app(_, 3)(f);
boost::bind( boost::apply<int>(), _1, 3 )(f);
// app(_, x)(g);
boost::bind( boost::apply<int>(), _1, x )(g);
boost::bind( boost::apply<int>(), _1, boost::ref(x) )(g);
}
You are saying that in the general case we can't decide between the last two
lines, so we shouldn't support references. But I'm not sure that this is
true. It seems to me that the rule is that I should use ref(x) if my x will
outlive the function object, as in the above, and a plain x otherwise, and
it will "just work".
> boost::lambda's "solution" is to always take reference parameters;
> this is why we have
>
> (_1 + _2)( 5, 7 ) // no, not 12--it's illegal
No, not correct. In the bind equivalent to app(_, x)(f), x is always copied
by default. It's f that is passed by reference.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk