calling bind with literals

I don't know if this was discussed at an earlier point, but I have a suggestion for a workaround of the forwarding problem. The main issue is whether you want to allow literals to be called from the bind_t operator(). I believe it's possible to change the semantics to the same as those within the bind call. In the current implementation of bind, bind( function, ref( object1 ), "literal" )( object2, "No literal" ) object2 is passed by reference, and "No literal" will not work due to binding a literal to a reference. However, I believe it possible to define semantics like this: bind( function, ref( object1 ), "literal" )( object2, "Literal allowed" ) object2 is passed by value, the literal is now allowed bind( function, ref( object1 ), "literal" )( ref( object2 ), "Literal allowed" ) object2 is passed by reference through the reference wrapper, and the literal is still allowed. There are several steps needed to convert the bind/mem_fn to these semantics (roughly): For mem_fn: 1. Change the semantics of mem_fn_template of the reference function to non reference (pass by value). 2. Add another operator() which uses a reference_wrapper. For bind: 3. Add a traits which processes the argument type to give the right semantics: template <class T> argument_traits { typedef T type; }; template <class T> argument_traits<reference_wrapper<T> > { typedef T& type; }; template <class T> argument_traits<reference_wrapper<T const> > { typedef T const& type; }; 4. Remove the reference from the argument type in bind_template.hpp from A1& to A1 for all N for operator(). 5. Process the list_av_N type by argument_traits instead of A1&, A2&, ... 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? Best, John

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. Doug

Douglas Gregor <gregod@cs.rpi.edu> writes:
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.
Or any rvalue for that matter.
Going to passing by value would take us further from that ideal equivalence.
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

On May 6, 2004, at 8:50 PM, David Abrahams wrote:
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
This is the way to go for now, and will cover 99% of the cases, or more. But we should not start feeling two content with the situation, the forwarding problem still needs to get solved at the language level :) Jaakko

jajarvi <jajarvi@cs.indiana.edu> writes:
On May 6, 2004, at 8:50 PM, David Abrahams wrote:
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
This is the way to go for now, and will cover 99% of the cases, or more. But we should not start feeling two content with the situation, the forwarding problem still needs to get solved at the language level :)
I guess you missed the big stink I made about that in Sydney? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

On Thursday 06 May 2004 09:50 pm, David Abrahams wrote:
Going to passing by value would take us further from that ideal equivalence.
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
Agreed. Doug

I'd like to get up the learning curve on some corner of boost and at the same time improve my socket stream reader/writer code by refactoring to add protocol parsers by configuration(socket/port), so I can build generic data-gateway interface. I'm looking for suggestions please. Here's some of the pertinent interfaces.... class ACE_Event_Handler<STREAM> has-a Socket<STREAM> + handle_input() - recv(Message*&) +send(Message *) + handle_output() - recv_header(Message*&) - recv_body(Message*&) class MessageParser + EnumProtocol protocolType(MessageHeader&) + Message *parse(Buffer&) class Message : ACE_Message_Block<NO_SYNCH> + void rd_ptr(int) + void wr_ptr(int) + uchar *rd_ptr() + uchar *wr_ptr() Any suggestions welcomed

I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
I second that. Maybe n==3 anyone? Best, John -- John Torjo Freelancer -- john@torjo.com -- http://www.torjo.com/logview/ - viewing/filtering logs is just too easy!

John Torjo <john.lists@torjo.com> writes:
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
I second that. Maybe n==3 anyone?
Fine with me. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

John Torjo wrote:
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
I second that. Maybe n==3 anyone?
Many older compilers have problems with T& / T const & overloading, even if they support partial ordering. This ordering case was recently 'fixed' in TC1, I believe.

"Peter Dimov" <pdimov@mmltd.net> writes:
John Torjo wrote:
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
I second that. Maybe n==3 anyone?
Many older compilers have problems with T& / T const & overloading, even if they support partial ordering.
Which ones? Don't some also bind temps to T& when that's all you supply? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Peter Dimov" <pdimov@mmltd.net> writes:
John Torjo wrote:
I agree. IMO the best answer for now is to generate the 2^N overloads of operator() for some user-selectable N. Unary and binary functions are so common that IMO usually N==2 will do it.
I second that. Maybe n==3 anyone?
Many older compilers have problems with T& / T const & overloading, even if they support partial ordering.
Which ones?
I'm not sure, it's been a while. I recall that EDG 2.40 and earlier couldn't order the two templates (in the const lvalue case, ordinary overloading rules apply otherwise); there may be others.
Don't some also bind temps to T& when that's all you supply?
Borland and MSVC 6 do that, with a warning.

"Peter Dimov" <pdimov@mmltd.net> writes:
Which ones?
I'm not sure, it's been a while. I recall that EDG 2.40 and earlier couldn't order the two templates (in the const lvalue case, ordinary overloading rules apply otherwise);
Oh, I'm not sure we should let that stand in our way. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (7)
-
David Abrahams
-
Dill, John
-
Douglas Gregor
-
jajarvi
-
John Torjo
-
Mike Winter
-
Peter Dimov