简体   繁体   English

自定义迭代器运算符重载

[英]Custom iterator operator overloading

I am trying to implement -> operator of a custom Iterator.我正在尝试实现->自定义迭代器的运算符。 However I am not getting how to define them precisely.但是我不知道如何精确定义它们。

My Iterator class and MapNode are defined like:我的 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>;
};

Now I want to overload operator->, but the problem is I am not exactly getting how to return pointer of pair of key and value where iterator is currently pointing:现在我想重载 operator->,但问题是我不知道如何返回迭代器当前指向的键和值对的指针:

My current implementation is :我目前的实现是:

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

But I am afraid that this will cause memory leaks as the ValueType pointer memory won't be deallocated ever.但是我担心这会导致内存泄漏,因为 ValueType 指针内存永远不会被释放。

Can someone guide me on how can this be done correctly?有人可以指导我如何正确完成此操作吗?

Please help.请帮忙。

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

I would start by storing the values in the MapNode in an std::pair :我首先将 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>;
};

Then the iterator can just return the address of that pair.然后迭代器可以只返回该对的地址。

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

The cast is a little ugly, but that's why you encapsulate it inside a piece of code you rarely have to look at.演员表有点难看,但这就是为什么你把它封装在一段你很少看的代码中。

If what you are really worried about is the potential for leaking memory, you could just return a unique_ptr to the pair .如果您真正担心的是内存泄漏的可能性,您可以将unique_ptr返回给pair This will ensure that the new 'd pair will be deleted whenever it is no longer referenced.这将确保new 'd 对在不再被引用时将被删除。

The syntax would be:语法是:

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

Alternatively since std::pair can be copied you could just return the pair by value if the types of Key_T and Mapped_T are likely to be copyable also..或者,由于std::pair可以被复制,如果Key_TMapped_T的类型也可能是可复制的,则您可以按值返回该pair

Depending on the possible types of Key_T and Mapped_T you need to be careful about those types being references when using pair in template code like this.根据Key_TMapped_T的可能类型,在这样的模板代码中使用 pair 时,您需要注意这些类型是引用。 Can cause headaches.会引起头痛。

See: std::pair of references请参阅: std::pair of references

If you really really really want to return a pointer to something you can do something like this really hacky thing:如果你真的真的很想返回一个指向某物的指针,你可以做这样的事情:

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

But you will likely end up regretting it.但你很可能最终会后悔。

You have to write a wrapper, something like你必须写一个包装器,比如

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

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

and your iterator becomes:你的迭代器变成:

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演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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