Re: calling bind with literals

"Douglas Gregor" <gregod@cs.rpi.edu> wrote in message news:<200405061958.52886.gregod@cs.rpi.edu>...
On Thursday 06 May 2004 05:32 pm, Dill, John wrote:
I believe that this can be done, but doesn't justify whether it should be done. There are several issues that I see at the moment.
A. Changes the semantics of everyone's bind and mem_fn, no biggy there ;-). B. Pass by value is silent, not sure how many copies of the argument will be generated if pass-by-value.
But at the same time there is an advantage.
a. You can use literals in calling your bind functions.
What do you all think?
I don't like the change.
Ideally, bind(f, _1, _2, _3)(x, y, z) would be exactly equivalent to f(x, y, z). The current bind() implementation gives us nearly this equivalence because it passes by reference, except that we get a failure at compile time if one tries to pass a literal. Going to passing by value would take us further from that ideal equivalence.
I see your point. But, what if instead of argument_traits being pass by value, it by default passes by T const&? What could be done is to have the bind_t arguments be passed by const reference, and then use reference_wrapper to do type-selection to pass by reference. It still supports literals, and passes by T const& when it can, but everything that is passed by reference must have a ref( object ). The compiler would fail if you try to pass a reference without a reference_wrapper because it by default tries to pass a T const&. This wouldn't require the 2^N overloads but would require you to do a ref( object ) for everything passed by reference. This might also be a workaround for those compilers that don't support T& and T const& overloading. I think that this should be addressed, either through overloading, or maybe this idea might be feasible. I think the implementation of this aspect of bind is worth doing. Best, John

On Friday 07 May 2004 10:30 am, Dill, John wrote:
I see your point. But, what if instead of argument_traits being pass by value, it by default passes by T const&? What could be done is to have the bind_t arguments be passed by const reference, and then use reference_wrapper to do type-selection to pass by reference. It still supports literals, and passes by T const& when it can, but everything that is passed by reference must have a ref( object ). The compiler would fail if you try to pass a reference without a reference_wrapper because it by default tries to pass a T const&. This wouldn't require the 2^N overloads but would require you to do a ref( object ) for everything passed by reference. This might also be a workaround for those compilers that don't support T& and T const& overloading.
So we'd be trading lvalue support for literal support. In my experience, lvalues are _much_ more important than literals[*], and we've had these semantics for a really long time (they'll be part of the C++ Library TR), so it will take a truly killer argument to change this. [*] Thinking of my own work, where I use lots of bind expressions, I remember only once having to name a temporary to get around the T& issue with bind, but can thinking of at least 4 places where I pass lvalues through bind. Doug

Douglas Gregor <gregod@cs.rpi.edu> writes:
On Friday 07 May 2004 10:30 am, Dill, John wrote:
I see your point. But, what if instead of argument_traits being pass by value, it by default passes by T const&? What could be done is to have the bind_t arguments be passed by const reference, and then use reference_wrapper to do type-selection to pass by reference. It still supports literals, and passes by T const& when it can, but everything that is passed by reference must have a ref( object ). The compiler would fail if you try to pass a reference without a reference_wrapper because it by default tries to pass a T const&. This wouldn't require the 2^N overloads but would require you to do a ref( object ) for everything passed by reference. This might also be a workaround for those compilers that don't support T& and T const& overloading.
So we'd be trading lvalue support for literal support. In my experience, lvalues are _much_ more important than literals[*],
It's literals and rvalues. Not that I support the proposed trade, but I should point out that rvalues are important, especially for function composition. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Dill, John wrote:
"Douglas Gregor" <gregod@cs.rpi.edu> wrote in message news:<200405061958.52886.gregod@cs.rpi.edu>...
Ideally, bind(f, _1, _2, _3)(x, y, z) would be exactly equivalent to f(x, y, z). The current bind() implementation gives us nearly this equivalence because it passes by reference, except that we get a failure at compile time if one tries to pass a literal. Going to passing by value would take us further from that ideal equivalence.
I see your point. But, what if instead of argument_traits being pass by value, it by default passes by T const&? What could be done is to have the bind_t arguments be passed by const reference, and then use reference_wrapper to do type-selection to pass by reference. It still supports literals, and passes by T const& when it can, but everything that is passed by reference must have a ref( object ).
Technically, bind supports character literals since they are lvalues. It is the rvalues that it has a problem with. Your suggestion is not feasible because in general you do not have control over the call site. As an example, consider std::for_each; it obviously doesn't wrap the argument with ref().
participants (4)
-
David Abrahams
-
Dill, John
-
Douglas Gregor
-
Peter Dimov