簡體   English   中英

自定義迭代器運算符重載

[英]Custom iterator operator overloading

我正在嘗試實現->自定義迭代器的運算符。 但是我不知道如何精確定義它們。

我的 Iterator 類和 MapNode 定義如下:

template <typename Key_T,typename Mapped_T>
class Map<Key_T,Mapped_T>::Iterator
{
    MapNode<Key_T,Mapped_T>* curr;
}

template <typename Key_T,typename Mapped_T>
class MapNode
{
    Key_T key;
    Mapped_T value;
    MapNode *up,*down,*prev,*next;
    friend class Map<Key_T,Mapped_T>;
};

現在我想重載 operator->,但問題是我不知道如何返回迭代器當前指向的鍵和值對的指針:

我目前的實現是:

template <typename Key_T,typename Mapped_T>
std::pair<const Key_T, Mapped_T>*
Map<Key_T,Mapped_T>::Iterator::operator->() const
{
    const Key_T currKey = (this->curr)->key;
    const Mapped_T currVal = (this->curr)->value;

    ValueType* vt = new ValueType(std::make_pair(currKey,currVal));

    return vt;
}

但是我擔心這會導致內存泄漏,因為 ValueType 指針內存永遠不會被釋放。

有人可以指導我如何正確完成此操作嗎?

請幫忙。

[ValueType is defined as std::pair<const Key_T, Mapped_T>]

我首先將 MapNode 中的值存儲在std::pair

template <typename Key_T,typename Mapped_T>
class MapNode
{
    std::pair<Key_T, Mapped_T> value;
    MapNode *up,*down,*prev,*next;
    friend class Map<Key_T,Mapped_T>;
};

然后迭代器可以只返回該對的地址。

template <typename Key_T,typename Mapped_T>
std::pair<const Key_T, Mapped_T> *
Map<Key_T,Mapped_T>::Iterator::operator->() const
{
    using ptr = std::pair<const Key_T, Mapped_T> *;
    return (ptr)(&(curr->value));
}

演員表有點難看,但這就是為什么你把它封裝在一段你很少看的代碼中。

如果您真正擔心的是內存泄漏的可能性,您可以將unique_ptr返回給pair 這將確保new 'd 對在不再被引用時將被刪除。

語法是:

template <typename Key_T,typename Mapped_T>
std::unique_ptr<std::pair<const Key_T, Mapped_T>>
Map<Key_T,Mapped_T>::Iterator::operator->() const
{
    const Key_T currKey = (this->curr)->key;
    const Mapped_T currVal = (this->curr)->value;

    return std::make_unique<ValueType>(std::make_pair(currKey,currVal));
}

或者,由於std::pair可以被復制,如果Key_TMapped_T的類型也可能是可復制的,則您可以按值返回該pair

根據Key_TMapped_T的可能類型,在這樣的模板代碼中使用 pair 時,您需要注意這些類型是引用。 會引起頭痛。

請參閱: std::pair of references

如果你真的真的很想返回一個指向某物的指針,你可以做這樣的事情:

template <typename T> class myIterator {
  T m_current;
public:
  bool next() { move_to_next(m_current); } // Or however you increment.
  T& read() { m_current; }
};

但你很可能最終會后悔。

你必須寫一個包裝器,比如

template <typename Key, typename Value>
struct Wrapper
{
    std::pair<const Key&, Value>* operator -> () { return &p; }

    std::pair<const Key&, Value> p;   
};

你的迭代器變成:

template <typename Key_T,typename Mapped_T>
class Map<Key_T,Mapped_T>::Iterator
{
public:
    // ...

    Wrapper<Key_T, Mapped_T> operator->() const { return {{curr->key, curr->value}}; }
private:
    MapNode<Key_T,Mapped_T>* curr;
};

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM