2008-09-26 68 views
2

我需要帮助理解一些C++运算符重载语句。类声明如下:运算符为C++映射重载

template <class key_t, class ipdc_t> 
class ipdc_map_template_t : public ipdc_lockable_t 
{ 
    ... 
    typedef map<key_t, 
      ipdc_t*, 
      less<key_t>> map_t; 
    ... 

类的创建者创建了一个迭代器的内部映射结构:

struct iterator : public map_t::iterator 
{ 
    iterator() {} 
    iterator(const map_t::iterator & it) 
     : map_t::iterator(it) {} 
    iterator(const iterator & it) 
     : map_t::iterator(
      *static_cast<const map_t::iterator *>(&it)) {} 
    operator key_t() {return ((this->operator*()).first);}   // I don't understand this. 
    operator ipdc_t*() const {return ((this->operator*()).second);} // or this. 

}; 

并开始()和结束()返回begin()和地图的结束():

iterator begin() {IT_ASSERT(is_owner()); return map.begin();} 
iterator end() {return map.end();} 

我的问题是,如果我有一个迭代,我怎么使用这些重载拿到钥匙和价值?

ipdc_map_template_t::iterator iter; 
    for(iter = my_instance.begin(); 
      iter != my_instance.end(); 
     ++iter) 
    { 
     key_t my_key = ??????; 
     ipdc_t *my_value = ??????; 

    } 
+0

下面提供的解决方案是不够好(用,但该值,PE指针问题可能),所以在不会详细说明...但无论如何:使用隐式强制转换作为合成糖是坏的和危险的设计,恕我直言... – paercebal 2008-09-26 20:57:43

回答

6

这些类型转换操作符,所以你可以这样做:

{ 
    key_t key = iter; 
    ipdc_t *val = iter; 
} 

或者,由于ipdc_map_template::iterator是的std::map::iterator一个子类,你仍然可以使用原有的存取(我觉得这更易读):

{ 
    key_t key = (*iter).first; 
    ipdc_t *val = (*iter).second; 

    // or, equivalently 
    key_t key = iter->first; 
    ipdc_t *val = iter->second; 

} 
2

该类的创建者已经重写了演员操作符。 所以通过将iter分配给正确类型的对象,它应该通过方法自动将自身转换为正确的值。

N.B.:值类型被存储为指针。因此,当您提取值时,您需要指定指向您在地图界面中指定的值类型的指针。

typedef ipdc_map_template_t<int,std::string> MyMap; 
MyMap mymap; 

for(MyMap::iterator iter = mymap.begin(); 
        iter != mymap.end(); 
        ++iter) 
    { 
      int   my_key = iter; 
      std::string* my_value = iter; 

    } 

不确定我同意在这里采取的方向。 这是否使代码更具可读性?我会坚持老式的地图迭代器听起来更有用。这个容器是在你需要的某个专业库中定义的,还是看看boost指针容器会有好处?

+0

你能验证你的代码?我想你是对的,但有一件事:地图是操纵价值的指针,而不是价值本身。所以我想用户将不得不做“std :: string * my_value = iter;”......或者我应该去睡一下...... :-p – paercebal 2008-09-26 20:55:51

+0

只是这样。但是当你只得到类的部分定义时,很难验证代码。 – 2008-09-26 20:57:18

2

operator key_t()和operator ipdc_t *()都是转换定义。因此,考虑到在类中定义一个迭代器,你应该能够简单地分配您的变量:

ipdc_map_template_t::iterator iter; 
    for(iter = my_instance.begin(); 
     iter != my_instance.end(); 
     ++iter) 
    { 
      key_t my_key = iter; 
      ipdc_t my_value = iter; 
    }