【发布时间】:2011-12-07 18:21:56
【问题描述】:
我正在编写自己的 C++ STL 映射容器实现。现在我正在尝试实现迭代器。它应该允许您执行类似 iter->first 和 iter->second 的操作,它们分别返回键/值,并且 iter 是对象而不是指针。我想知道我应该如何超载这个?这有点令人困惑,因为我不确定返回类型应该是什么;我想它必须是第一个/第二个成员的对象。返回对包装器/接口对象或类似对象的引用是否很常见?
【问题讨论】:
我正在编写自己的 C++ STL 映射容器实现。现在我正在尝试实现迭代器。它应该允许您执行类似 iter->first 和 iter->second 的操作,它们分别返回键/值,并且 iter 是对象而不是指针。我想知道我应该如何超载这个?这有点令人困惑,因为我不确定返回类型应该是什么;我想它必须是第一个/第二个成员的对象。返回对包装器/接口对象或类似对象的引用是否很常见?
【问题讨论】:
您的问题的答案是肯定的。您应该返回代理对象或对代理对象的引用以获取该行为。
【讨论】:
如果你真的是指 C++ 标准库,那么 map 的 value_type 就是 pair。一对有成员first 和second。取消引用 map 中的迭代器会得到 pair。
【讨论】:
map 的 value_type 仍然是 pair ;-p
是的,您需要一个代理来保存相关参考。
至于类型:标准库迭代器通常取消引用 value_type 类型的东西。对于map<K,V>,值类型是std::pair<K, V>(或者更确切地说是pair<key_type, mapped_type>),这是您获取first/second 接口的地方。
(Stephan Lavavej 的讲座之一解释了 MSVC++ 实现如何对set 和map 使用相同的底层数据结构;唯一的区别是set::value_type 等于set::key_type,而map::value_type 是pair<key_type, mapped_type> . 这样你就可以通过简单的特征检查来区分这两者,但迭代器接口实际上是相同的。)
【讨论】:
std::map<K,V>::iterator 迭代 std::pair<K,V> 类型的对象。
【讨论】:
标准映射的value_type是std::pair<const KeyType, MappedType>。
为了实现正常的指针语义,operator* 返回一个引用,而operator-> 返回一个指针。
//minimal example
#include <utility>
#include <cstdio>
struct It
{
std::pair<const int, int> pair;
std::pair<const int, int>* operator->() { return &pair; }
std::pair<const int, int>& operator*() { return pair; }
};
int main()
{
It it = {std::make_pair(10, 20) };
(*it).second = 30;
std::printf("%d %d\n", it->first, it->second);
}
【讨论】: