find() 无法识别我的自定义迭代器

find() does not recognize my custom iterator

提问人:berkeozgur 提问时间:11/17/2023 最后编辑:berkeozgur 更新时间:11/19/2023 访问量:107

问:

我为一个简单的文本编辑器编写了一个名为 Text_Iterator 的自定义迭代器。但是,像 find() 这样的 STL 算法不会将其识别为合法的迭代器。

我的代码是:

using Line = std::vector<char>;

class Text_iterator {
    std::list<Line>::iterator ln;
    Line::iterator pos;

public:
    Text_iterator(std::list<Line>::iterator ll, Line::iterator pp)
        : ln{ll}, pos{pp} {}

    char& operator*() { return *pos; }
    Text_iterator& operator++();
    Text_iterator& operator--();

    bool operator==(const Text_iterator& other) const 
    {
        return (ln == other.ln && pos == other.pos);
    }
    bool operator!=(const Text_iterator& other) const
    {
        return (!(*this == other));
    }
};

当我尝试在算法中使用此迭代器时,例如在 find() 中,我收到以下错误:

1>...\xutility(861,56): error C2794: 'value_type': is not a member of any direct or indirect base class of 'std::iterator_traits<_InIt>'
1>        with
1>        [
1>            _InIt=Text_iterator
1>        ]

为什么它不注册为合法迭代器?

编辑:适用于以下附加声明:

using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = char;
using pointer = char*;
using reference = char&;
C++ 迭代器 std

评论

3赞 Evg 11/17/2023
它不能满足所有 STL 要求。请参阅此处:en.cppreference.com/w/cpp/named_req/BidirectionalIterator
0赞 Remy Lebeau 11/17/2023
@Evg使用满足 InputIterator 或 ForwardIterator 的迭代器,则不需要 BidirectionalIteratorstd::find()
0赞 Sam Varshavchik 11/17/2023
因为它不是一个合法的迭代器。合法的迭代器必须具有指定迭代器属性的特定成员。它们应该在涵盖高级 C++ 模板主题的教科书中解释。
0赞 Evg 11/17/2023
@RemyLebeau当然,但是在OP的代码中,我猜他们的目的是定义一个双向迭代器。operator++()operator--()
0赞 Pepijn Kramer 11/17/2023
另请参阅:en.cppreference.com/w/cpp/iterator/iterator_traits,您可能还需要声明等。difference_type

答:

2赞 Remy Lebeau 11/17/2023 #1

错误消息抱怨 std::iterator_traits 在应用于您的类时没有成员。value_typeText_iterator

您的类返回一个 ,但您的类没有别名的成员,例如:operator*char&value_typechar

class Text_iterator {
    ...

public:
    typedef char value_type;
    // or: using value_type = char;
    // or: typedef std::iterator_traits<Line::iterator>::value_type value_type;
    // or: using value_type = st::iterator_traits<Line::iterator>::value_type;
    ...
};

std::find()仅适用于满足 InputIterator 或 ForwardIterator 要求的迭代器。

因此,您需要

  • 将所需的成员添加到您的类中(不仅还有几个成员),以便默认成员可以找到它们。value_typestd::iterator_traits
  • 为您的班级专门化 std::iterator_traits

评论

0赞 berkeozgur 11/17/2023
如果它不是这样的负担,我究竟需要在我的定义中添加什么才能使其工作?我阅读了您分享的链接,但对于对 C++ 相对陌生的人来说,它们似乎有点晦涩难懂。
0赞 Remy Lebeau 11/17/2023
我链接的 2 个需求页面解释了您需要为类实现的所有运算符和成员
0赞 berkeozgur 11/17/2023
我将更详细地研究它们。感谢您抽出宝贵时间接受采访。如果我再次被卡住,我以后可能会打扰你,如果没事的话。:)
3赞 Remy Lebeau 11/17/2023
用现代 C++ 编写自定义迭代器