简体   繁体   中英

how to use overloading increment operator for a iterator

I want to implement a generic map by a linked list. I've been attempting to overload the ++ operator to move an iterator through a list but I have problem using the new operator.

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

Here is the overloading:

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

I want to use the ++ operator in another method in mtmMap:

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

but I get these errors:

"lvalue required as increment operand"

"increment of read-only location"

Make the operator a member function of the iterator. BTW also please prefer more modern idioms.

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

Please note, that I have not tested this code. It might contain bugs, and is only meant to show the concept to you. I use some C++11 specific syntax. For most compilers you'll still have to activate C++11 support.

I assume, that this is a homework assignment. Before you write anything like this in production code, stop and think, if std::map , or std::list really don't do the trick for you. They save you from a lot of headaches.

It seems that you implemented operator++ on the MtmMap , not on the iterator. Your design is wrong (using member iterator variable???). You want to be able to do this:

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

so implement your iterator class based on that.

Just so you know, this is not an object, it's a pointer. You'd have to dereference it - (*this)++ . That might get your code working as it is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM