I am implementing an iterator via iterator facade. The container that the iterator is being used with can only return dereferenced values by value (not by reference). If I implement the dereference() function (for facade) by returning a value (instead of reference) then it appears that the iterator works properly. The most important operation that does _not_ work is that the iterator cannot be used with bind(). (bind cannot be used with non-const return types.) If I change the iterator to return a reference type then the iterator functions still work and so does bind. What is the proper way of implementing an iterator with this limitation so that it works properly with bind? In the past, I keep a mutable value member along with the iterator to store the last dereferenced value. Of course this is fraught with problems. Is there an example iterator that demonstrates the proper way of doing this? Is there some kind of proxy class that can be used to overcome this limitation? Thanks for your help, ...Duane
Duane Murphy wrote:
I am implementing an iterator via iterator facade. The container that the iterator is being used with can only return dereferenced values by value (not by reference).
If I implement the dereference() function (for facade) by returning a value (instead of reference) then it appears that the iterator works properly.
The most important operation that does _not_ work is that the iterator cannot be used with bind(). (bind cannot be used with non-const return types.)
Sorry, I can't imagine what you mean. Of course bind works with non-const return types: int f(int x) { return x + 1; } int three = bind(f, 2)();
If I change the iterator to return a reference type then the iterator functions still work and so does bind.
Please post your code. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
David Abrahams wrote:
Duane Murphy wrote:
I am implementing an iterator via iterator facade. The container that the iterator is being used with can only return dereferenced values by value (not by reference).
If I implement the dereference() function (for facade) by returning a value (instead of reference) then it appears that the iterator works properly.
The most important operation that does _not_ work is that the iterator cannot be used with bind(). (bind cannot be used with non-const return types.)
Sorry, I can't imagine what you mean. Of course bind works with non-const return types: [...]
Probably the following: std::for_each( first, last, boost::bind( f, _1 ) ); When *first returns a non-const rvalue, bind can't take it.
Peter Dimov wrote:
David Abrahams wrote:
Duane Murphy wrote:
I am implementing an iterator via iterator facade. The container that the iterator is being used with can only return dereferenced values by value (not by reference).
If I implement the dereference() function (for facade) by returning a value (instead of reference) then it appears that the iterator works properly. The most important operation that does _not_ work is that the iterator cannot be used with bind(). (bind cannot be used with non-const return types.)
Sorry, I can't imagine what you mean. Of course bind works with non-const return types: [...]
Probably the following:
std::for_each( first, last, boost::bind( f, _1 ) );
When *first returns a non-const rvalue, bind can't take it.
I guess the answer is to make the reference type const, then. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
David Abrahams wrote:
Peter Dimov wrote:
David Abrahams wrote:
Duane Murphy wrote:
I am implementing an iterator via iterator facade. The container that the iterator is being used with can only return dereferenced values by value (not by reference).
If I implement the dereference() function (for facade) by returning a value (instead of reference) then it appears that the iterator works properly. The most important operation that does _not_ work is that the iterator cannot be used with bind(). (bind cannot be used with non-const return types.)
Sorry, I can't imagine what you mean. Of course bind works with non-const return types: [...]
Probably the following:
std::for_each( first, last, boost::bind( f, _1 ) );
When *first returns a non-const rvalue, bind can't take it.
I guess the answer is to make the reference type const, then.
That will suppress the iterator's writability, though. I hope it's desired. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
--- At Sun, 5 Dec 2004 07:34:38 -0500, David Abrahams wrote:
David Abrahams wrote:
Peter Dimov wrote:
David Abrahams wrote:
Duane Murphy wrote:
I am implementing an iterator via iterator facade. The container that the iterator is being used with can only return dereferenced values by value (not by reference).
If I implement the dereference() function (for facade) by returning a value (instead of reference) then it appears that the iterator works properly. The most important operation that does _not_ work is that the iterator cannot be used with bind(). (bind cannot be used with non-const return types.)
Sorry, I can't imagine what you mean. Of course bind works with non-const return types: [...]
Probably the following:
std::for_each( first, last, boost::bind( f, _1 ) );
When *first returns a non-const rvalue, bind can't take it.
Bingo! This is the exact case that I am trying to test.
I guess the answer is to make the reference type const, then.
That will suppress the iterator's writability, though. I hope it's desired.
No, it's not really. I was hoping for some kind of proxy interface where a const proxy could be return and dereferencing the proxy would return the object. Maybe holding the current value in the iterator is the correct solution. ...Duane
Duane Murphy wrote:
--- At Sun, 5 Dec 2004 07:34:38 -0500, David Abrahams wrote:
Sorry, I can't imagine what you mean. Of course bind works with non-const return types: [...]
Probably the following:
std::for_each( first, last, boost::bind( f, _1 ) );
When *first returns a non-const rvalue, bind can't take it.
Bingo! This is the exact case that I am trying to test.
I guess the answer is to make the reference type const, then.
Well really the answer is to fix bind so that it works with rvalues, at least for a few arguments.
That will suppress the iterator's writability, though. I hope it's desired.
No, it's not really.
I was hoping for some kind of proxy interface where a const proxy could be return and dereferencing the proxy would return the object.
Maybe holding the current value in the iterator is the correct solution.
You can always reimplement operator* in your derived iterator: reference const operator*() const { return this->dereference(); } HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (3)
-
David Abrahams
-
Duane Murphy
-
Peter Dimov