2012-01-28 80 views
0

公众视野我有一个秘密范围的Boost.BiMap的一类,我想出口的该地图的一部分公众视野。我有下面的代码的两个问题:暴露私人范围的Boost.BiMap迭代

class Object { 

    typedef bimap< 
     unordered_set_of<Point>, 
     unordered_multiset_of<Value> 
    > PointMap; 

    PointMap point_map; 

public: 
    ??? GetPoints(Value v) { 
    ... 
} 

的第一个问题是,如果我的迭代的方法来获取与Value关联是正确的Point的。以下是我用来遍历点的代码。我的问题是,如果我循环正确,因为我发现,我必须包括it->first == value条件,如果这是需要给出一个更好的界面,我可能不知道不知道。

PointMap::right_const_iterator it; 
it = point_map.right.find(value); 
while (it != point_map.right.end() && it->first == val) { 
    /* do stuff */ 
} 

第二个问题是什么是不暴露bimap的迭代器提供GetPoints(在???返回类型以上)的公众视野,因为它似乎呼叫者就必须了解point_map.right.end()的最佳途径。任何有效的结构(如引用列表或集合)都可以工作,但我在创建集合方面有点遗憾。

谢谢!

回答

0

第一个问题:

由于您使用您的bimap类型的右侧unordered_multiset_of集合类型,这意味着它将与std::unordered_multimap兼容的接口。 std::unordered_multimap具有成员函数equal_range(const Key& key)它返回迭代器的std::pair,一个指向具有指向一个过去具有相同的关键要素的范围的端部所需的密钥和一个第一个元素。使用它可以使用匹配键迭代范围,而无需将键与迭代条件中的值进行比较。

请参阅参考资料http://www.boost.org/doc/libs/1_41_0/libs/bimap/doc/html/boost_bimap/the_tutorial/controlling_collection_types.htmlhttp://en.cppreference.com/w/cpp/container/unordered_multimap/equal_range

第二个问题:

构建指针或引用到具有匹配的值的元素的列表或其他实际容器和返回这是低效的,因为它总是将需要O(n)的空间,而让用户遍历原始bimap中的范围只需要返回两个只需要O(1)内存的迭代器。

您可以写一个成员函数直接返回迭代器,例如

typedef PointMap::right_const_iterator match_iterator; 

std::pair<match_iterator, match_iterator> GetPoints(Value v) { 
    return point_map.right.equal_range(v); 
} 

,或者您可以编写具有开始()和end()成员函数返回这两个迭代器,并让您GetPoints()成员函数返回一个类型的对象呈现容器状接口的代理类:

class MatchList { 

    typedef PointMap::right_const_iterator iterator; 

    std::pair<iterator, iterator> m_iters; 

public: 

    MatchList(std::pair<iterator, iterator> const& p) : m_iters(p) {} 

    MatchList(MatchList const&) = delete; 

    MatchList(MatchList&&) = delete; 

    MatchList& operator=(MatchList const&) = delete; 

    iterator begin() { return m_iters.first; } 

    iterator end() { return m_iters.second; } 
}; 

这是一个好主意,使之不可复制,不可移动和不可分配,因为用户可以以其他方式保持代理类的副本,并尝试访问它(就像我通过删除相关成员函数上面完成)之后迭代器可能失效。

第一种方式是指写更少的代码,第二装置呈现一种较为常见的接口给用户(以及允许在代理类隐藏更多的东西,如果以后需要修改实现)。

+0

关于第二个问题的第一种方法,PointMap是否需要公开作用域?我可以为公共接口使用某种类型的泛型迭代器吗? – 2012-01-28 22:19:06

+0

PointMap仍然可以是私人的。我的示例代码中的typedef match_iterator需要是公开的,因此它可以被类之外的代码使用。 – user450018 2012-01-29 08:49:35