【问题标题】:List iterator implementation in map implementation - trouble在地图实现中列出迭代器实现 - 麻烦
【发布时间】:2016-04-17 15:01:14
【问题描述】:

DataType 的模板类 List 中的迭代器实现。

 template <DataType>
 class List{
        ...

    class myIterator
    {
    public:
        typedef myIterator self_type;
        typedef Node<DataType>* pointer;

        myIterator(pointer ptr) : ptr_(ptr) { }
        self_type operator++() {
            self_type i = *this;
            if (ptr_) ptr_ = ptr_->Next();
            return i;
        }
        int operator*() { if (ptr_ ) return ptr_->Data(); else return 0; }
        bool operator==(const self_type& rhs) {
            if (!ptr_ && !rhs.ptr_) return true;
            return (ptr_ && rhs.ptr_ && rhs.ptr_->Data()==ptr_->Data());
        }
        bool operator!=(const self_type& rhs) {
            return !(*this==rhs);
        }
    private:
        pointer ptr_ = nullptr;
    };

    myIterator begin() { return myIterator(head); }
    myIterator end() { return myIterator(nullptr); }
};

用途:

void remove(const KeyType& key) {
            if (!this->containsKey(key)) {
                return;
            }
            for (List<Pair, CompareFunction>::myIterator it = this->_pairs.begin();
            it != this->_pairs.end(); ++it) {
                Pair cur_pair = *it;
                if (cur_pair.first == key) {
                    this->_pairs.Delete(cur_pair);
                    this->_size--;
                }
            }
        }

该函数头相关代码:

template <class KeyType, class ValueType, class CompareFunction = std::less<KeyType> >
    class MtmMap {

    public:
        class Pair {
        public:
            Pair() :first(KeyType()) {} ////////////////////
            Pair(const KeyType& key, const ValueType& value)
                : first(key), second(value) {}

            const KeyType first;
            ValueType second;

            ~Pair() = default;

            Pair& operator=(const Pair& pair) {
                this->second = pair.second;
                return *this;
            }
        };

目的: 我在该循环中尝试做的是遍历整个列表并找到键与给定相同的对,然后删除整个对。

问题:

*it

被解释为 int,在我们的例子中我猜是从 MtmMap 泄漏的,因为在我的“main”中:

typedef MtmMap<int, int> IntMap;
typedef IntMap::Pair IntPair;

IntMap map1(10);
map1.insert(IntPair(1, 2));
map1.remove(1);

错误:

" cannot convert from "int" to "mtm::MtmMap<int,int,std::less<KeyType>>::Pair" ""

编辑: 我还有一个问题,在下一段代码中:

const ValueType& operator[](const KeyType& key) const {
            for (List<Pair, CompareFunction>::myIterator it = this->_pairs.begin();
            it != this->_pairs.end(); ++it) {

在这种迭代器的使用中,编译器喊道:

Error   C2662   List<mtm::MtmMap<int,int,std::less<KeyType>>::Pair,CompareFunction>::myIterator List<mtm::MtmMap<KeyType,int,CompareFunction>::Pair,CompareFunction>::begin(void):  cannot convert 'this' from "const List<mtm::MtmMap<int,int,std::less<KeyType>>::Pair,CompareFunction>" to "List<mtm::MtmMap<int,int,std::less<KeyType>>::Pair,CompareFunction> &"

据我了解,这里存在 const 正确性问题。我不能将迭代器设为 const,那么我将无法使用它进行迭代。我该如何处理?

【问题讨论】:

  • 注意:你应该用指针来实现迭代器——不要测试有效性(只是让程序崩溃),不要比较内容(只是比较指针地址)。如果需要,还可以提前指针,并让程序兑现(如果该提前无效)。
  • 我觉得这里缺少一些细节。 *at 是什么意思?我在您的代码中的任何地方都没有看到。请提供minimal reproducible example
  • 可能是*it 的拼写错误?
  • 我选择的正是相关的代码,ead的答案非常好。
  • 对于第二个问题:您的 begin() 和 end() 不正确,因此您不能在 const 成员函数中调用它们。您应该像这样声明它们 const:myIterator begin() const { return myIterator(head); }(可能不是那么容易)或定义 begin() 和 end() 的第二个 const 版本或丢弃 operator[] 的 const 限定符(简单但不好的选择)

标签: c++ list dictionary iterator nodes


【解决方案1】:

我认为缺少一些细节,但是

int operator*() { if (ptr_ ) return ptr_->Data(); else return 0; }

仅在 ptr_->Data() 是 int 时才有效,这可能不是您的意图。返回值不应该是DataType吗?

【讨论】:

  • 是的,这正是问题所在。现在我只需要考虑如何返回 ptrnull,因为它不是 DataType 并且编译器会抱怨它。但是很好,谢谢。或者也许可以在这里使用 throw。
  • 嗯...奇怪,如果签名是 DataType,我如何返回 DataType 对象或 nullptr?有什么建议吗?
  • 如果 ptr 为空,您应该引发异常或返回默认值
  • 我又添了一个小麻烦'希望你还在这里给我一些建议,谢谢。
猜你喜欢
  • 2012-02-04
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多