
Hi, I have this code that isn't compiling because of the "forwarding problem" limitation of boost::bind: std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, _1)); The problem is that an implicit conversion is required between the reference type of the difference_iterator and the argument type of writeVInt. It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1))); ^^^^^^^^^^^^ ^ I know it's not pretty, but it sorta does what we want. Thoughts? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Hi,
I have this code that isn't compiling because of the "forwarding problem" limitation of boost::bind:
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, _1));
Nice namespace name.
The problem is that an implicit conversion is required between the reference type of the difference_iterator and the argument type of writeVInt.
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1))); ^^^^^^^^^^^^ ^
I know it's not pretty, but it sorta does what we want. Thoughts?
Have you tried to implement it? ;-) The current bind way to work around the above problem is to use an adaptor that fixes its signature to, for example, void(fu const &). Choices are function<void(fu const &)> and make_adaptable<void, fu const &> (in boost/bind/make_adaptable.hpp). Lambda also provides its own mechanisms.

"Peter Dimov" <pdimov@mmltd.net> writes:
David Abrahams wrote:
Hi,
I have this code that isn't compiling because of the "forwarding problem" limitation of boost::bind:
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, _1));
Nice namespace name.
Name was changed to protect the innocent. It's a class name, really.
The problem is that an implicit conversion is required between the reference type of the difference_iterator and the argument type of writeVInt.
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1))); ^^^^^^^^^^^^ ^
I know it's not pretty, but it sorta does what we want. Thoughts?
Have you tried to implement it? ;-)
'course not! ;-) Is it hard?
The current bind way to work around the above problem is to use an adaptor that fixes its signature to, for example, void(fu const &). Choices are function<void(fu const &)> and make_adaptable<void, fu const &> (in boost/bind/make_adaptable.hpp).
Huh! Where's make_adaptable documented?
Lambda also provides its own mechanisms.
I'll look, thanks. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1))); ^^^^^^^^^^^^ ^
I know it's not pretty, but it sorta does what we want. Thoughts?
Have you tried to implement it? ;-)
'course not! ;-)
Is it hard?
Doesn't seem easy at first sight, even if we limit ourselves to 100% conforming compilers.
The current bind way to work around the above problem is to use an adaptor that fixes its signature to, for example, void(fu const &). Choices are function<void(fu const &)> and make_adaptable<void, fu const &> (in boost/bind/make_adaptable.hpp).
Huh! Where's make_adaptable documented?
I could've sworn that it was documented in bind.html. But it's not. It's only listed in the "files" section. Another one for the to-do list.

David Abrahams wrote:
Hi,
I have this code that isn't compiling because of the "forwarding problem" limitation of boost::bind:
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, _1));
The problem is that an implicit conversion is required between the reference type of the difference_iterator and the argument type of writeVInt.
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1)));
How about constifying the original sequence? Something like: std::for_each( make_difference_iterator( constify( p->second.begin())) , make_difference_iterator( constify( p->second.end())) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1))); Of course, constify it's just too easy to implement: template<class T> const T& constify(T &val) { return val; } Best, John

John Torjo <john.lists@torjo.com> writes:
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1)));
How about constifying the original sequence?
That wouldn't help.
Something like:
std::for_each( make_difference_iterator( constify( p->second.begin())) , make_difference_iterator( constify( p->second.end())) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1)));
Of course, constify it's just too easy to implement:
template<class T> const T& constify(T &val) { return val; }
The problem is that dereferencing a difference_iterator yields an rvalue. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
John Torjo <john.lists@torjo.com> writes:
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1)));
How about constifying the original sequence?
That wouldn't help.
duh :D what was I thinking? However, I looked for difference iterator, and did not find any docs or anything else. So, for the above case, what's the difference_iterator's value_type and reference, and what's the writeVInt's signature? Best, John

John Torjo <john.lists@torjo.com> writes:
David Abrahams wrote:
John Torjo <john.lists@torjo.com> writes:
It seems to me that, since I know that binding to an rvalue is required, we ought to have a way to say "force this to be a const ref". I thought of something like
std::for_each( make_difference_iterator(p->second.begin()) , make_difference_iterator(p->second.end()) , boost::bind(&fu::writeVInt, &prox, boost::cref(_1)));
How about constifying the original sequence?
That wouldn't help.
duh :D what was I thinking?
However, I looked for difference iterator, and did not find any docs or anything else.
No, it's just something I cooked up here.
So, for the above case, what's the difference_iterator's value_type and reference,
say they're both int.
and what's the writeVInt's signature?
let's say it's void fu::writeVInt(something_that_int_is_convertible_to) -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
David Abrahams
-
John Torjo
-
Peter Dimov