Ste*_*ein 3 c++ unordered-map std-ranges range-based-loop
我想根据某些条件从地图中删除一些元素:
#include <unordered_map>
#include <ranges>
#include <iostream>
int main() {
std::unordered_map<int, int> numbers = {{1,2}, {2,1}, {3,2}, {4,5}};
auto even = [](auto entry){return entry.second %2 == 0;};
for(auto& [key, val] : numbers | std::views::filter(even)) {
numbers.erase(val);
}
for(auto& [key, val] : numbers) {
std::cout << key << " " << val << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
但似乎我正在使基于范围的循环所需的迭代器无效:
4 5
3 2
1 2
Run Code Online (Sandbox Code Playgroud)
我知道如何使用迭代器显式地执行此操作,但是是否有一种基于范围的简洁方法来删除基于过滤器的元素?
我建议你使用std::erase_if(),如下所示:
std::erase_if(numbers, [](auto entry) {return entry.second % 2 == 0; });
Run Code Online (Sandbox Code Playgroud)
如果您想要一个范围解决方案,并且不需要就地更改,您可以执行如下操作(此代码仅在 C++23 中编译):
numbers = numbers | std::views::filter(even) | std::ranges::to<decltype(numbers)>();
Run Code Online (Sandbox Code Playgroud)
我不确定,但根据文档,下面的代码可能比上面的正常范围代码具有更好的性能:
auto temp_numbers = numbers | std::views::filter(even) | std::ranges::to<decltype(numbers)>();
numbers.swap(temp_numbers);
Run Code Online (Sandbox Code Playgroud)
operator=正如你在for中看到的std::unordered_map,它的移动赋值运算符的复杂度是线性的,但是它的移动构造函数的复杂度是恒定的swap(),并且它的方法的复杂度也是恒定的,所以看起来性能更好。但是,我对此没有任何基准。
| 归档时间: |
|
| 查看次数: |
292 次 |
| 最近记录: |