如何在std::multimap的subrange上正确应用std::ranges::min以获取指定键的最小值元素?
问题分析与解决方案
你的代码编译失败主要有两个核心原因,我们一步步拆解:
1. 投影参数的语法错误
你写的&decltype(a)::value_type::second是不合法的C语法。虽然decltype(a)::value_type确实能正确指向std::pair<const int, int>,但C中获取类成员指针时,不能通过decltype(对象)::嵌套类型::成员这种方式来写,编译器无法正确解析这个表达式为有效的成员指针。
2. VS2019对C++20 Ranges的兼容性细节
VS2019 16.11版本对C++20标准库的Ranges部分支持还不算完全成熟,一些偏语法层面的写法(比如非常规的成员指针写法)可能会触发编译问题。
修改方案(两种可选)
方案一:修正成员指针的写法
直接明确指定成员所属的具体类型,让编译器能正确识别成员指针:
#include <algorithm> #include <map> #include <ranges> #include <utility> // 确保std::pair的定义被编译器看到 int main() { std::multimap<int, int> a{ { 1, 2 }, { 1, 3 }, { 4, 5 }, { 4, 6 }, }; const auto [b, c] = a.equal_range(a.cbegin()->first); // 明确使用std::pair<const int, int>的second成员指针 auto d = std::ranges::min(std::ranges::subrange{ b, c }, {}, &std::pair<const int, int>::second); }
方案二:使用Lambda作为投影(更推荐)
Lambda投影更直观,可读性更强,同时兼容性更好,几乎不会触发编译器解析问题:
#include <algorithm> #include <map> #include <ranges> int main() { std::multimap<int, int> a{ { 1, 2 }, { 1, 3 }, { 4, 5 }, { 4, 6 }, }; const auto [b, c] = a.equal_range(a.cbegin()->first); // 用lambda明确提取每个元素的second值作为排序依据 auto d = std::ranges::min(std::ranges::subrange{ b, c }, {}, [](const auto& elem) { return elem.second; }); }
额外说明
如果你的需求只是获取最小的second值(而不是整个元素),还可以用std::views::values简化代码:
auto min_second_value = std::ranges::min(std::ranges::subrange{b, c} | std::views::values);
以上修改后,代码就能正常编译运行,并且准确获取第一个键对应元素中second值最小的那个元素(在你的例子中就是(1, 2))。
内容的提问来源于stack exchange,提问作者Jupiter
相关产品推荐
相关产品推荐

