
Hi Jeff, sure your suggestion would work. My original question was really aimed at the maintainer of the iterator library. It described what I think is a minor shortcoming in the transform_iterator that could be improved upon. Regards Sebastian
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Jeff Flinn Sent: Donnerstag, 22. Oktober 2009 15:09 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [iterator] Automatic definition oftransform_iterator reference_type
[Posted once again with better subject]
I've encountered a problem when using boost::mem_fn in transform_iterators. In the attached example, I've chained two transform_iterators. The first iterator returns an Obj by value and
second extracts a member of the temporary object. The example shows
the return value is not quite what is expected.
boost::mem_fn(&Obj::m_member) returns an int const&. The transform_iterator uses the return value of the UnaryFunction template parameter to initialize his value_type. In the given example, this logic seems too simple. At least if the UnaryFunction is of type boost::_mfi::dm the transform_iterator could do better:
If Reference is boost::use_default If UnaryFunction is boost::_mfi::dm && Iterator::value_type is not a reference itself reference = boost::remove_reference( result_of(UnaryFunction) ) Else reference = result_of(UnaryFunction) Else reference = Reference
Is this too much of a special case to fix it in the
Sebastian Theophil wrote: the that transform_iterator?
The same logic would apply to all (unknown) functors that returned references to member variables. In general, the transform_iterator can probably not decide if a reference returned from a UnaryFunction will cease to exist when the temporary is destroyed. It could have been a global object. On the other hand, transform_iterators should work correctly if only boost objects are used, shouldn't they?
I'd like to hear what you think, Sebastian
#include "boost/iterator/transform_iterator.hpp" #include <vector>
struct Obj { Obj(int n) : m_member(n) {} Obj(Obj const& obj) : m_member(obj.m_member) {} ~Obj() { m_member=INT_MIN; }
int m_member; };
static Obj GetObjByValue( int n ) { return Obj(n); }
void main() { std::vector<int> v(1, 5);
int n=*boost::make_transform_iterator( boost::make_transform_iterator( v.begin(), GetObjByValue ), boost::mem_fn(&Obj::m_member) ); _ASSERT(n==INT_MIN); }
How about composing the function rather than the iterator ala:(untested)
int n = *make_transform_iterator ( v.begin() , bind( &Obj::m_member, bind(GetObjByValue, _1));
Jeff
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Sebastian Theophil . stheophil@think-cell.com Software Engineer think-cell Software GmbH . Invalidenstr. 34 . 10115 Berlin, Germany http://www.think-cell.com . phone +49-30-666473-10 . toll-free (US) +1-800-891-8091 Directors: Dr. Markus Hannebauer, Dr. Arno Schoedl . Amtsgericht Berlin-Charlottenburg, HRB 85229