std::multimap equal _range 和 C++20 std::views::values 不能很好地协同工作
std::multimap equal _range and C++20 std::views::values do not work nicely together
我有以下代码,它可以工作,但 C++20 版本看起来并不比 C++17 版本好多少。我的猜测问题是 multimap
equal_range
returns a pair
and ranges 无法确定这是一对有效的迭代器。
有没有办法用更短更好的方式来写这个?
#include <iostream>
#include <map>
#include <ranges>
int main() {
std::multimap<bool,int> oddness{{false,2}, {true,3}, {true,47}, {false,74656}};
// nice, does not work:
// oddness.equal_range(true) | std::views::values;
// works:
oddness | std::views::values;
// working code:
auto odds = oddness.equal_range(true);
const auto odds_view = std::views::values(std::ranges::subrange(odds.first, odds.second));
for (const auto& odd : odds_view) {
std::cout << odd << std::endl;
}
}
问题是 equal_range
return 是一个 pair<It, It>
,(不幸的是)它本身不是一个范围。在我看来,这是更不幸的遗留 API 决定之一 - 因为我们有这个优秀的名字,但它做了一些......不太好。
您过去可以使用 pair<It, It>
并轻松将其转换为 subrange
,但这不一定有效并已被删除(首先在 LWG3281 and then the rest in LWG3404 中)。并非所有的迭代器对实际上都是范围(一些算法 return 两个迭代器不是 - 如 minmax_element
或 mismatch
)。
不过没关系,我们可以自己写一个显式的:
struct pair_to_range_t {
template <typename I>
friend constexpr auto operator|(std::pair<I, I> const& pr, pair_to_range_t) {
return std::ranges::subrange(pr.first, pr.second);
}
};
inline constexpr pair_to_range_t pair_to_range{};
然后你可以写:
oddness.equal_range(true) | pair_to_range | std::views::values;
我有以下代码,它可以工作,但 C++20 版本看起来并不比 C++17 版本好多少。我的猜测问题是 multimap
equal_range
returns a pair
and ranges 无法确定这是一对有效的迭代器。
有没有办法用更短更好的方式来写这个?
#include <iostream>
#include <map>
#include <ranges>
int main() {
std::multimap<bool,int> oddness{{false,2}, {true,3}, {true,47}, {false,74656}};
// nice, does not work:
// oddness.equal_range(true) | std::views::values;
// works:
oddness | std::views::values;
// working code:
auto odds = oddness.equal_range(true);
const auto odds_view = std::views::values(std::ranges::subrange(odds.first, odds.second));
for (const auto& odd : odds_view) {
std::cout << odd << std::endl;
}
}
问题是 equal_range
return 是一个 pair<It, It>
,(不幸的是)它本身不是一个范围。在我看来,这是更不幸的遗留 API 决定之一 - 因为我们有这个优秀的名字,但它做了一些......不太好。
您过去可以使用 pair<It, It>
并轻松将其转换为 subrange
,但这不一定有效并已被删除(首先在 LWG3281 and then the rest in LWG3404 中)。并非所有的迭代器对实际上都是范围(一些算法 return 两个迭代器不是 - 如 minmax_element
或 mismatch
)。
不过没关系,我们可以自己写一个显式的:
struct pair_to_range_t {
template <typename I>
friend constexpr auto operator|(std::pair<I, I> const& pr, pair_to_range_t) {
return std::ranges::subrange(pr.first, pr.second);
}
};
inline constexpr pair_to_range_t pair_to_range{};
然后你可以写:
oddness.equal_range(true) | pair_to_range | std::views::values;