如何将重载增量运算符用于迭代器

how to use overloading increment operator for a iterator

本文关键字:运算符 用于 迭代器 重载      更新时间:2023-10-16

我想通过链表实现一个通用映射。我一直在尝试重载++运算符以在列表中移动迭代器,但是使用新运算符时遇到问题。

template <class KeyType, class ValueType, class CompareFunction = std::less<KeyType> >
class MtmMap {
    public:
        class Node{
            public:
                const Pair*  data;
                Node* next;
                Node()
                    : data(NULL),next(NULL){}
                Node(const Pair pair){
                    data=new Pair(pair);
                    data=&pair;
                    next=NULL;
                }
            };
            Node* iterator;
            // ...
};

这是重载:

Node* operator++(){
    iterator=iterator->next;
    return iterator;
}

我想在 mtmMap 中的另一种方法中使用 ++ 运算符:

void insert(const Pair pair){
 for(begin();iterator->next->data;this++){
 }

但我收到这些错误:

"需要左值作为增量操作数"

"只读位置的增量"

使运算符成为迭代器的成员函数。顺便说一句,也请更喜欢更现代的成语。

template <typename KeyType, typename ValueType,
          typename CompareFunction = std::less<KeyType> >
class MtmMap {
    public:
        class Node {
            public:
                const Pair*  data;
                // the nodes are managed by the linked list,
                // so use a unique_ptr<> here.
                unique_ptr<Node> next;
                // you'll probably want to avoid this. Why should you
                // have an empty node in your list?
                Node() : data{nullptr}, next{nullptr} {};
                // instead have this:
                Node(const Pair* d) : data{d}, next{nullptr} {};
                // don't do this.
                // When you use raw pointers, you don't want to own the objects. 
                // in case your linked list has to own the objects,
                // use unique_ptr<> instead.
                // if you do, always prefer initializer lists, when possible.
                /* Node(const Pair pair) {
                    data=new Pair(pair);
                    data=&pair;
                    next=NULL;
                } */
        };
    private:
        // the start node will be managed by the list.
        // When it is released, all the nodes are released automatically.
        // But not the data, they point to.
        unique_ptr<Node> startNode = nullptr;
    public:
        class iterator {
            private:
                Node* current;
            public:
                iterator(Node* c) current{c} {};
                bool operator == (const Node& other) {
                    return current == other.current;
                }
                Pair& operator*() {
                    return *(current->data);
                }
                // ... some other operators. For more details, see:
                // http://en.cppreference.com/w/cpp/iterator
                iterator& operator ++ () {
                    current = (current == nullptr) ? nullptr : current->next.get();
                    return *this;
                }
        };
        iterator begin() { return { startNode }; }
        iterator end() { return { nullptr }; }
        // ...
};
// now you can to this:
MtmMap m;
// ... populate the map
for( auto& currentPair: m ) {
    // do whatever you need with currentPair.
}

请注意,我还没有测试过这段代码。它可能包含错误,并且仅用于向您展示概念。我使用一些 C++11 特定的语法。对于大多数编译器,您仍然需要激活 C++11 支持。

我假设,这是一个家庭作业。在生产代码中编写这样的东西之前,请停下来想一想,如果std::map,或者std::list真的不为你做这个伎俩。他们让你免于很多头痛。

您似乎在MtmMap上实现了operator++,而不是在迭代器上。您的设计是错误的(使用成员迭代器变量???)。您希望能够执行以下操作:

for(auto it = begin(); it != end(); it++) // idiomatic

因此,基于此实现迭代器类。

你知道,this不是一个对象,而是一个指针。你必须取消引用它 - (*this)++ .这可能会使您的代码按原样工作。