对于返回prvalue并返回悬空引用的迭代器,moveiterator被破坏

move_iterator is broken for iterators returning prvalues and returns dangling reference

本文关键字:返回 迭代器 moveiterator 引用 于返回 prvalue      更新时间:2023-10-16

我在STL源中查找了std::move_iterator<Iterator>,发现它返回Iterator::value_type&&。当Iterator::reference是右值并且与Iterator::value_type&不同时,这会导致不正确的行为。

我有一个类,它的代理对象为reference(类似于std::vector<bool>),它可以隐式转换为value_type。普通迭代器只是取消引用该代理(输入迭代器要求允许这样做),但std::move_iterator调用对value_type的强制转换会产生开销,然后返回对创建的临时对象的悬挂引用。

由于某种原因,std::move_iterator仍然可以与std::vector<bool>一起使用(可能是因为bool是一个简单的类型,并且悬空的bool&&不会导致错误),但与我的类不一样。这让我很困惑,我不知道如何修复它,我认为这是STL中的一个错误。

以下是GCC 4.8.1:中std::move_iterator的简化来源

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;
};

C++委员会知道您遇到的问题。LWG第2106期正在跟踪此问题。该问题目前处于公开状态,这意味着该决议尚未决定。

更新

LWG第2106期在C++17中及时被接受。PR位于问题的底部(此更新中更正了链接)。