【问题标题】:how to use overloading increment operator for a iterator如何为迭代器使用重载增量运算符
【发布时间】:2016-01-14 15:07:26
【问题描述】:

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

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++){
 }

但我收到以下错误:

“需要作为增量操作数的左值”

“只读位置的增量”

【问题讨论】:

  • 请修正压痕并平衡大括号。另外,请澄清您要做什么。在 C++ 中,“迭代器”指的是一种数据类型,但您显然在容器类中创建了一个名为 iterator 的成员变量。
  • 在 STL 帮派建立更好的方法之前,将迭代状态“混入”正在迭代的集合中是相当普遍的。从标准库中寻找灵感。
  • 另外,data=&amp;pair; 会给你留下一个无效的指针,因为pair 是一个函数参数。这也是内存泄漏。

标签: c++ operator-overloading increment


【解决方案1】:

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

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::mapstd::list 真的不适合你。它们使您免于很多麻烦。

【讨论】:

    【解决方案2】:

    您似乎在MtmMap 上实现了operator++,而不是在迭代器上。您的设计是错误的(使用成员迭代器变量???)。你希望能够做到这一点:

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

    所以基于它来实现你的迭代器类。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-12
      • 2011-05-18
      • 1970-01-01
      • 2011-10-18
      • 2020-06-14
      • 1970-01-01
      • 2011-12-07
      • 2013-09-07
      相关资源
      最近更新 更多