迭代者是否对自己的立场有良知性?

Do iterators have conciousness of their position?

本文关键字:良知 是否 自己的 迭代      更新时间:2023-10-16

>假设我有一个地图,为了简单起见,键是一个int,并且能够通过最少的编译示例重现问题。就我自己而言,关键是一个更复杂的野兽。

我想重用这张地图来创建另一张地图,使用不同的键:比如说enum而不是int。为此,我有两个函数可以让我将int转换为enum,反之亦然。

我没有重写整个类,而是使用组合,并将我的地图(在本例中为map<int,int>Inside 我的新类 myMap 中。

我从以下实现开始,但我的类 A 中的自定义迭代器有问题。我没有选择继承std::iterator,也没有选择继承map<int,int>::iterator而是再次使用组合:

class myMap
{
private:
std::map<int, int> m;
public:
typedef std::map<int, int> map_type;
typedef enum { X1=0, X2, X3, INVALID } key_type;
typedef int mapped_type;
typedef pair<key_type, mapped_type> value_type;
/* conversions from int to key_type and vice versa */
friend key_type int2K(int k);
friend int K2int(key_type k);
class Iterator
{
private:
map_type::iterator it;
key_type K;
public:
Iterator(map_type::iterator & i) : 
it(i), K(int2K(i->first)) {} //<= Error if i is not valid (points to the end)
};
typedef Iterator iterator;
iterator end() { return iterator(m.end()); }
// other parts of the class skipped for concisness  
};
myMap::key_type int2K(int k) {
return (k == 0 ? myMap::X1 : 
(k == 1 ? myMap::X2 : 
(k == 3 ? myMap::X3 : 
myMap::INVALID))); }
int K2int(myMap::key_type k) { return k; }

当我将 myMap 的迭代器初始化到映射的末尾时,它失败了:

myMap m;
myMap::iterator i = m.end(); //<= fails here

有没有办法在我的构造函数中检查迭代器是否指向地图的末尾?如果是这样,如何?

简短的回答是否定的。正如 zett42 在问题的评论中所说,迭代器位置已知的唯一位置是在迭代器调用端。

为了解决这个问题,正如 Jarod42 所建议的那样,只有在取消引用迭代器时,才能通过计算等效键K找到解决方案:

Iterator(map_type::iterator & i): it(i) {};
value_type operator*() {
return { int2K(it->first), it->second};
} 

注意:在之前的答案中,我试图通过复制迭代器,将副本递增 1,并检查副本是否仍然等于原始指针(指向末尾)来测试迭代器是否在其容器的末尾。

但正如 zett42 指出的那样,这是行不通的: - 递增指向容器末尾的迭代器应该是未定义的行为 - 即使是一个简单的指针也有资格作为迭代器。在这种情况下,看到此解决方案不起作用是微不足道的。

/* DISCLAIMER: Not working ! */
Iterator(map_type::iterator & i) : it(i), K(INVALID) 
{
map_type::iterator j = i;
j++;
if(i!=j) K = int2K(i->first);
}