move_iterator is broken for iterators returning prvalues and returns dangling reference

Viewed 399

I've looked in the STL sources for std::move_iterator<Iterator> and found out that it returns Iterator::value_type&&. This leads to incorrect behaviour when Iterator::reference is an rvalue and not the same as Iterator::value_type&.

I have a class with a proxy object as reference (like in std::vector<bool>), which can implicitly cast to value_type. The normal iterator just dereferences to this proxy (the input iterator requirements allow this), but std::move_iterator invokes casting to value_type with an overhead and then returns a dangling reference to the created temporary object.

std::move_iterator still works with std::vector<bool> for some reason (probably because bool is a simple type, and a dangling bool&& doesn't cause an error), but not with my class. It's confusing me and I don't understand how to fix it, I think it's a bug in STL.

Here is the simplified piece of source for std::move_iterator from GCC 4.8.1:

template <typename Iterator>
class move_iterator {
public:
    typedef typename iterator_traits<Iterator>::value_type value_type;
    typedef value_type&& reference;

    reference operator*() const {
        return std::move(*it);
    }

private:
    Iterator it;
};
1 Answers
Related