2

是否可以在 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 );
}

我可以解决它,但如果这一个班轮工作会很好。

最好的

4

2 回答 2

10

查看std::ranges::min's 函数签名:

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 = {} );

它返回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)有效的表达式 which is Out,但这是不可能的,因为我们不能将 a 分配给其他:range_value_t<R>*std::pair<const int, int>*std::pair<const int, int>

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);
于 2020-10-22T06:36:39.757 回答
5

而不是std::ranges::min你可以std::ranges::min_element这样使用:

auto lowest = *std::ranges::min_element(std::move(usage_table), 
                                        {}, 
                                        &std::map<int,int>::value_type::second);

此外,目前还不清楚你为什么要moveing map,它似乎没有做任何有用的事情。

于 2020-10-22T05:14:34.563 回答