迭代者是否对自己的立场有良知性?
Do iterators have conciousness of their position?
>假设我有一个地图,为了简单起见,键是一个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);
}
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C/C++预处理器是否可以检测一些编译器选项
- 迭代者是否对自己的立场有良知性?