Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-04-16 06:20:35


Dill, John wrote:
>>> While having pass-by-value
>>> may be more convenient and occur more often, the
>>> counter-intuitiveness of the semantics will lead to subtle bugs in
>>> people's code who misunderstand or forget bind's behavior in this
>>> area.
>>
>> A bold prediction in the face of contradictory evidence.
>
> Can you elaborate?

In general, arguments of the form "feature X causes frequent real and
documented problems right now" carry more weight than "I boldly predict that
feature X will inevitably cause problems in the future, and you should
change it now as I say, or else."

> You may have no problems understanding the
> library, but the first time I tried to bind with a reference, I ran
> into the same confusion. I am speaking from my own limited
> experience with the library. I've read the documentation:

[...]

> I know this makes it explicit that you need a ref or cref to have
> bind store a reference to an object, but there is no reasoning behind
> this design decision in the documentation, or that I can find in the
> implementation and I've not stumbled across it in the mail archives.

Reasons, in no particular order:

- Lifetime. Storing a reference is unsafe; you need to ensure that the
function object returned by the bind() expression will not outlive the
referenced entity. The current semantics are safe by default.

- Consistency with the first argument. The bound function object is copied,
and so are the arguments. It is not possible to infer, in general, whether
the function object should be copied or not. When you learn about ref(), you
can easily apply your knowledge to bind expressions that store a reference
to a function object: bind( ref(f), _1, 0 );

- You can tell whether the bind() expression refers to outside entities by
local inspection. If you see no ref(), you can reasonably expect a
self-contained function object.

- It is not possible to detect, in general, whether an argument needs to be
passed by reference:

struct F
{
    void operator()(int x);
    void operator()(long & x);
};


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