公开私有范围的 Boost.BiMap 迭代器的公共视图

发布于 2024-12-29 19:14:40 字数 842 浏览 0 评论 0原文

我在类中有一个私有范围的 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()。任何有效的结构(例如引用列表或集合)都可以,但我对如何创建集合有点迷失。

谢谢!

I have a privately scoped Boost.BiMap in a class, and I would like to export a public view of part of this map. I have two questions about the following code:

class Object {

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

    PointMap point_map;

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

The first question is if my method of iteration to get the Point's associated with a Value is correct. Below is the code I'm using to iterate over the points. My question is if I am iterating correctly because I found that I had to include the it->first == value condition, and wasn't sure if this was required given a better interface that I may not know about.

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

The second question is what is the best way to provide a public view of the GetPoints (the ??? return type above) without exposing the bimap iterator because it seems that the caller would have to know about point_map.right.end(). Any efficient structure such as a list of references or a set would work, but I'm a bit lost on how to create the collection.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事与诗 2025-01-05 19:14:40

第一个问题:

由于您在 bimap 类型的右侧使用 unordered_multiset_of 集合类型,这意味着它将具有与 std 兼容的接口: :unordered_multimapstd::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);
}

,或者您可以编写一个代理类,通过让 begin() 和 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; }
};

最好使其不可复制、不可移动和不可分配(就像我上面通过删除相关成员函数所做的那样),因为用户可能会保留一个副本代理类的并在迭代器可能失效时尝试稍后访问它。

第一种方法意味着编写更少的代码,第二种方法意味着向用户呈现更通用的接口(并且如果稍后需要修改实现,则允许在代理类中隐藏更多内容)。

The first question:

Since you are using the unordered_multiset_of collection type for the right side of your bimap type, it means that it will have an interface compatible with std::unordered_multimap. std::unordered_multimap has the member function equal_range(const Key& key) which returns a std::pair of iterators, one pointing to the first element that has the desired key and one that points to one past the end of the range of elements that have the same key. Using that you can iterate over the range with the matching key without comparing the key to the value in the iteration condition.

See http://www.boost.org/doc/libs/1_41_0/libs/bimap/doc/html/boost_bimap/the_tutorial/controlling_collection_types.html and http://en.cppreference.com/w/cpp/container/unordered_multimap/equal_range for references.

The second question:

Constructing a list or other actual container of pointers or references to the elements with the matching values and returning that is inefficient since it's always going to require O(n) space, whereas just letting the user iterate over the range in the original bimap only requires returning two iterators, which only require O(1) memory.

You can either write a member function that returns the iterators directly, e.g.

typedef PointMap::right_const_iterator match_iterator;

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

or you can write a proxy class that presents a container-like interface by having begin() and end() member functions returning those two iterators, and have your GetPoints() member function return an object of that type:

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; }
};

It's a good idea to make it uncopyable, unmovable and unassignable (like I've done above by deleting the relevant member functions) since the user may otherwise keep a copy of the proxy class and try to access it later when the iterators could be invalidated.

The first way means writing less code, the second means presenting a more common interface to the user (and allows for hiding more stuff in the proxy class if you need to modify the implementation later).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文