2016-10-13 11 views
1

カスタムイテレータの->演算子を実装しようとしています。しかし、私はそれらを正確に定義する方法を知りません。カスタムイテレータ演算子オーバーロード

私のイテレータクラスと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>] 

答えて

1

私はstd::pairにMapNodeに値を格納することによって開始します:

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)); 
} 

キャストは少し醜いですが、それはあなたがめったに見る必要がないコードの一部にカプセル化する理由です。

0

何をについては本当に心配していると、メモリリークの可能性であるならば、あなただけのpairunique_ptrを返すことができます。これにより、newのペアが参照されなくなったときに必ず削除されます。

構文は次のようになります。

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::pairKey_TMapped_Tの種類もコピー可能であると思われる場合は、値だけでpairを返すことができますコピーすることができますので、...

によってはKey_TMapped_Tの可能なタイプについては、このようなテンプレートコードでペアを使用するときは、これらのタイプが参照になるように注意する必要があります。頭痛を引き起こす可能性があります。

参照:

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

しかし、あなたはおそらくそれを後悔することになります:std::pair of references

は、あなたが本当に本当に本当にあなたがこれは本当にハックの事のような何かを行うことができます何かへのポインタを返すようにしたい場合。

0

あなたは、

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

Demo

関連する問題