making bind and mem_fn results default constructible?

Hi Consider this example of mem_fn usage: struct X { int bar; }; std::vector<X> vec; .... boost::make_transform_iterator(vec.begin(), boost::mem_fn(&X::bar)); The above is, strictly speaking, _not_ a Random Access Traversal Iterator, or even a Forward Traversal Iterator, and would fail in otherwise concept conforming code (or in a potential concept-check). The problems lies in the function objects returned by boost::mem_fn and boost::bind not being default constructible, thus making the resulting iterator not default constructible which is required by the Forward Traversal concept. http://boost.org/libs/iterator/doc/new-iter-concepts.html#forward-traversal-... (The problem is even more pronounced if using the "old" Iterator Concepts.) I found an old (2002) mail by David Abrahams where he also noted the problem: http://lists.boost.org/MailArchives/boost/msg30420.php But it didn't seem to have resulted in any change of the codebase. I think use-cases similar to the one above are good motivation and hope this could be considered an acceptable improvement. Regards // Fredrik Blomqvist P.S. I realize it is very close to the branch for release and don't expect this to be added before that.

Fredrik Blomqvist wrote:
Hi
Consider this example of mem_fn usage:
struct X { int bar; }; std::vector<X> vec; .... boost::make_transform_iterator(vec.begin(), boost::mem_fn(&X::bar));
The above is, strictly speaking, _not_ a Random Access Traversal Iterator, or even a Forward Traversal Iterator, and would fail in otherwise concept conforming code (or in a potential concept-check).
The problems lies in the function objects returned by boost::mem_fn and boost::bind not being default constructible, thus making the resulting iterator not default constructible which is required by the Forward Traversal concept.
No, the problem lies in (the current implementation of) transform_iterator. It is not reasonable to require function objects to be default constructible, because few of them are, and in fact, the documentation places no such requirement on the function object.

Peter Dimov wrote:
Fredrik Blomqvist wrote:
Hi
Consider this example of mem_fn usage:
struct X { int bar; }; std::vector<X> vec; .... boost::make_transform_iterator(vec.begin(), boost::mem_fn(&X::bar));
The above is, strictly speaking, _not_ a Random Access Traversal Iterator, or even a Forward Traversal Iterator, and would fail in otherwise concept conforming code (or in a potential concept-check).
The problems lies in the function objects returned by boost::mem_fn and boost::bind not being default constructible, thus making the resulting iterator not default constructible which is required by the Forward Traversal concept.
No, the problem lies in (the current implementation of) transform_iterator. It is not reasonable to require function objects to be default constructible, because few of them are, and in fact, the documentation places no such requirement on the function object.
Ah, well, my intention wasn't really to focus on transform_iterator, I just used it as an example. Although I can see that you're right about it not being in sync with it's documentation. My point was that default-constructability would make creating _any_ kind of adaptor based on bind/mem_fn easier and more flexible. As long as the bound expression is default constructible a default constructor in bind/mem_fn would simply expose that and improve implementation convenience. The potential 'no default constructor' error would simply move to its "proper place" IMO. Am I missing something? // Fredrik Blomqvist

Fredrik Blomqvist wrote:
Ah, well, my intention wasn't really to focus on transform_iterator, I just used it as an example.
Yes, I know. Me too.
Although I can see that you're right about it not being in sync with it's documentation. My point was that default-constructability would make creating _any_ kind of adaptor based on bind/mem_fn easier and more flexible.
I'm not sure I agree. Adding a default constructor that may create a singular object is, in my experience, a design mistake. Any component that requires such a constructor is broken. The main purpose of this constructor (again, IME) is to allow you to shoot yourself in the foot, as is frequently the case with the iterators.

"Peter Dimov" <pdimov@mmltd.net> writes:
Fredrik Blomqvist wrote:
Hi
Consider this example of mem_fn usage:
struct X { int bar; }; std::vector<X> vec; .... boost::make_transform_iterator(vec.begin(), boost::mem_fn(&X::bar));
The above is, strictly speaking, _not_ a Random Access Traversal Iterator, or even a Forward Traversal Iterator, and would fail in otherwise concept conforming code (or in a potential concept-check).
The problems lies in the function objects returned by boost::mem_fn and boost::bind not being default constructible, thus making the resulting iterator not default constructible which is required by the Forward Traversal concept.
No, the problem lies in (the current implementation of) transform_iterator. It is not reasonable to require function objects to be default constructible, because few of them are, and in fact, the documentation places no such requirement on the function object.
Good point. We should use boost::optional here. Patches welcomed! -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (3)
-
David Abrahams
-
Fredrik Blomqvist
-
Peter Dimov