2017-06-16 10 views
-2

说我有一个地图,其中的关键是int为了简单起见,并能够用最少的编译示例重现此问题。在我的情况下,关键是一个更复杂的野兽。迭代器是否有意识的位置?

我想重复使用此地图来创建另一张地图,并使用不同的键:说一个enum而不是一个int。为此,我有两个功能允许我将int转换为enum,反之亦然。

而不是重写整个班级,我用的组合物,我把我的地图(在这种情况下map<int,int>在我的新类MYMAP。

我开始用下面的实现,但我有一个自定义的问题迭代器在我的课答:我没有选择从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 

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

+1

只有在引用'Iterator'时才可以转换。 – Jarod42

+2

在boost中检出iterator_facade – sp2danny

+0

@ sp2danny我知道iterator_facade,但它不会解决我的问题。我的问题是不知道迭代器需要完成什么接口,它更多的是我的迭代器类中的设计问题。 – Heyji

回答

1

简短的回答是否定的。正如问题评论中的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); 
} 
+0

[不起作用](http://coliru.stacked-crooked.com/a/27b9c61bec8ecd55)。你甚至认为这应该起作用?迭代器不需要持有关于容器的任何信息,即使是常规指针也可以作为迭代器。 – zett42

+0

@ zett42:谢谢你的评论。我已经更新了答案,您可能还想更新您的评论(以及您的投票:-) – Heyji

相关问题