自定义迭代器运算符重载
Custom iterator operator overloading
我正在尝试实现自定义迭代器的 ->
运算符。但是我不知道如何准确定义它们。
我的迭代器 class 和 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->,但问题是我不知道如何 return 迭代器当前指向的键和值对的指针:
我当前的实现是:
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>]
如果您真正担心的是内存泄漏的可能性,您可以 return 一个 unique_ptr
到 pair
。这将确保 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::pair
可以被复制,如果 Key_T
和 Mapped_T
的类型可能是也可复制..
根据 Key_T
和 Mapped_T
的可能类型,在像这样的模板代码中使用 pair 时,您需要注意这些类型是引用。会引起头痛。
参见:std::pair of references
如果你真的真的很想 return 一个指向某物的指针,你可以做这样的事情,这真的很骇人听闻:
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;
};
我首先将 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>;
};
然后迭代器可以 return 那对地址。
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));
}
转换有点难看,但这就是为什么您将它封装在一段您很少需要查看的代码中。
我正在尝试实现自定义迭代器的 ->
运算符。但是我不知道如何准确定义它们。
我的迭代器 class 和 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->,但问题是我不知道如何 return 迭代器当前指向的键和值对的指针:
我当前的实现是:
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>]
如果您真正担心的是内存泄漏的可能性,您可以 return 一个 unique_ptr
到 pair
。这将确保 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::pair
可以被复制,如果 Key_T
和 Mapped_T
的类型可能是也可复制..
根据 Key_T
和 Mapped_T
的可能类型,在像这样的模板代码中使用 pair 时,您需要注意这些类型是引用。会引起头痛。
参见:std::pair of references
如果你真的真的很想 return 一个指向某物的指针,你可以做这样的事情,这真的很骇人听闻:
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;
};
我首先将 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>;
};
然后迭代器可以 return 那对地址。
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));
}
转换有点难看,但这就是为什么您将它封装在一段您很少需要查看的代码中。