用 std::ranges::min 投影到 std::map
Projecting on a std::map with std::ranges::min
是否可以在 std::map 上投影?我尝试将 std::ranges::min 与投影一起使用,但它似乎抛出了我无法解释为什么它不喜欢的错误。
#include <set>
#include <iostream>
#include <ranges>
#include <vector>
#include <iostream>
#include <map>
#include <algorithm>
int main()
{
std::map<int, int> usage_table;
auto lowest = std::ranges::min( std::move(usage_table),
{},
&std::map<int,int>::value_type::second );
}
我可以解决这个问题,但如果这个衬垫能用就好了。
最佳
您可以像这样使用 std::ranges::min_element
而不是 std::ranges::min
:
auto lowest = *std::ranges::min_element(std::move(usage_table),
{},
&std::map<int,int>::value_type::second);
另外,不清楚你为什么要 move
ing map
,它似乎没有做任何有用的事情。
查看std::ranges::min
的函数签名:
template< ranges::input_range R, class Proj = std::identity,
std::indirect_strict_weak_order<
std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less >
requires std::indirectly_copyable_storable<ranges::iterator_t<R>, ranges::range_value_t<R>*>
constexpr ranges::range_value_t<R> min( R&& r, Comp comp = {}, Proj proj = {} );
它returns range_value_t<R>
这意味着value_type
的范围需要copyable
,所以ranges::min
需要indirectly_copyable_storable
这需要indirectly_copyable
需要 indirectly_writable
:
template<class Out, class T>
concept indirectly_writable =
requires(Out&& o, T&& t) {
*o = std::forward<T>(t);
*std::forward<Out>(o) = std::forward<T>(t);
const_cast<const std::iter_reference_t<Out>&&>(*o) = std::forward<T>(t);
const_cast<const std::iter_reference_t<Out>&&>(*std::forward<Out>(o)) =
std::forward<T>(t);
};
我们需要 *o = std::forward<T>(t)
是 Out
是 range_value_t<R>*
是 std::pair<const int, int>*
的有效表达式,但这是不可能的,因为我们无法分配 [=27] =] 给其他人:
std::pair<const int, int> a, b;
// use of deleted function 'std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&)'
a = b;
很遗憾,std::ranges::min
不能申请 std::map
:
// constraints not satisfied
std::ranges::min(std::map<int, int>{});
但是如果你想找到 std::map
的 key_type/mapped_type
的最小值,你可以只使用 c++20 范围适配器 std::views::keys/values
,它可以很好地与 std::ranges::min
:
std::map<int, int> usage_table{{5, -12}, {3, 4}};
// -12
auto lowest = std::ranges::min(usage_table | std::views::values);
是否可以在 std::map 上投影?我尝试将 std::ranges::min 与投影一起使用,但它似乎抛出了我无法解释为什么它不喜欢的错误。
#include <set>
#include <iostream>
#include <ranges>
#include <vector>
#include <iostream>
#include <map>
#include <algorithm>
int main()
{
std::map<int, int> usage_table;
auto lowest = std::ranges::min( std::move(usage_table),
{},
&std::map<int,int>::value_type::second );
}
我可以解决这个问题,但如果这个衬垫能用就好了。
最佳
您可以像这样使用 std::ranges::min_element
而不是 std::ranges::min
:
auto lowest = *std::ranges::min_element(std::move(usage_table),
{},
&std::map<int,int>::value_type::second);
另外,不清楚你为什么要 move
ing map
,它似乎没有做任何有用的事情。
查看std::ranges::min
的函数签名:
template< ranges::input_range R, class Proj = std::identity,
std::indirect_strict_weak_order<
std::projected<ranges::iterator_t<R>, Proj>> Comp = ranges::less >
requires std::indirectly_copyable_storable<ranges::iterator_t<R>, ranges::range_value_t<R>*>
constexpr ranges::range_value_t<R> min( R&& r, Comp comp = {}, Proj proj = {} );
它returns range_value_t<R>
这意味着value_type
的范围需要copyable
,所以ranges::min
需要indirectly_copyable_storable
这需要indirectly_copyable
需要 indirectly_writable
:
template<class Out, class T>
concept indirectly_writable =
requires(Out&& o, T&& t) {
*o = std::forward<T>(t);
*std::forward<Out>(o) = std::forward<T>(t);
const_cast<const std::iter_reference_t<Out>&&>(*o) = std::forward<T>(t);
const_cast<const std::iter_reference_t<Out>&&>(*std::forward<Out>(o)) =
std::forward<T>(t);
};
我们需要 *o = std::forward<T>(t)
是 Out
是 range_value_t<R>*
是 std::pair<const int, int>*
的有效表达式,但这是不可能的,因为我们无法分配 [=27] =] 给其他人:
std::pair<const int, int> a, b;
// use of deleted function 'std::pair<const int, int>& std::pair<const int, int>::operator=(const std::pair<const int, int>&)'
a = b;
很遗憾,std::ranges::min
不能申请 std::map
:
// constraints not satisfied
std::ranges::min(std::map<int, int>{});
但是如果你想找到 std::map
的 key_type/mapped_type
的最小值,你可以只使用 c++20 范围适配器 std::views::keys/values
,它可以很好地与 std::ranges::min
:
std::map<int, int> usage_table{{5, -12}, {3, 4}};
// -12
auto lowest = std::ranges::min(usage_table | std::views::values);