我正在尝试实现自定义迭代器的->
操作符。然而,我不知道如何精确地定义它们。
我的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>;
};
现在我想重载操作符->,但问题是我不知道如何返回迭代器当前指向的键和值对的指针:
我当前的实现是:
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>]
我将首先在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>;
};
则迭代器只能返回该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));
}
强制转换有点难看,但这就是为什么要将它封装在一段代码中,您几乎不需要看。
如果您真正担心的是潜在的内存泄漏,您可以将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_T
和Mapped_T
的类型也可能是可复制的,则可以按值返回pair
.
根据Key_T
和Mapped_T
的可能类型,在像这样的模板代码中使用pair时,需要注意这些类型是否是引用。会引起头痛。
参见:std::pair引用
如果你真的真的想要返回一个指针你可以做这样的事情:
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;
};
演示