Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

move_iterator is broken for iterators returning prvalues and returns dangling reference

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;
};
like image 287
lizarisk Avatar asked Dec 09 '13 13:12

lizarisk


1 Answers

The problem you are experiencing is known to the C++ committee. This problem is being tracked by LWG issue 2106. This issue is currently in Open status, meaning the resolution has not yet been decided upon.

Update

LWG issue 2106 was accepted in time for C++17. The PR is at the bottom of the issue (link corrected in this update).

like image 147
Howard Hinnant Avatar answered Nov 07 '22 15:11

Howard Hinnant