Boost logo

Boost Users :

Subject: [Boost-users] Calling boost::_mfi::dm on temporaries (e.g. in transform_iterator)
From: Sebastian Theophil (stheophil_at_[hidden])
Date: 2009-09-23 10:13:05


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 the
second extracts a member of the temporary object. The example shows that
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 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);
}

--
Sebastian Theophil . stheophil_at_[hidden]
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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net