0

我们如何将 unordered_multimap::local_iterator 更改为 unordered_multimap::iterator 或 unordered_multimap::const_iterator?我需要更改,因为我们无法使用 local_iterator 擦除元素,而擦除只能使用 iterator/const_iterator 来完成。如果有任何其他使用 local_iterator 擦除的方式,请提出建议。

4

2 回答 2

2

有点劳动密集型,但您可以遍历结果equal_range()直到找到正确的迭代器:

template<typename Cont>
typename Cont::iterator local_to_regular_iterator(Cont& c, typename Cont::local_iterator local_ite) {
  auto range = c.equal_range(local_ite->first);

  for(auto ite = range.first; ite != range.second; ++ite) {
    if(&ite->second == &local_ite->second) {
      return ite;
    }
  }

  throw std::out_of_range("huh?");
}

据我所知,这是你目前所能得到的。

于 2021-08-22T06:37:04.960 回答
1

您可以使用find_if算法来搜索具有相同地址的元素,如下所示:

auto it = std::ranges::find_if(m, 
    [ptr = std::addressof(*local_it)](const auto& e) -> bool
    {
        return ptr == std::addressof(e);
    }
    );

这是一个完整的代码片段:

#include <string_view>
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <ranges>
#include <memory>

int main()
{
    std::unordered_multimap<int, char> m;
    m.insert({1, 'a'});
    m.insert({1, 'b'});
    m.insert({2, 'c'});

    auto local_it = m.begin(m.bucket(1));
    std::cout << local_it->first << local_it->second << '\n';

    auto it = std::ranges::find_if(m, 
    [ptr = std::addressof(*local_it)](const auto& e) -> bool
    {
        return ptr == std::addressof(e);
    }
    );

    std::cout << it->first << it->second << '\n';

    return 0;
}

在这里运行它。

于 2021-08-22T08:08:49.270 回答