1

我想在将范围传递到动作或视图之前应用投影。考虑以下示例:

#include <iostream>
#include <range/v3/view/map.hpp>
#include <range/v3/action/sort.hpp>
#include <range/v3/algorithm/for_each.hpp>

int main()
{
    std::vector<std::string> strings{"1.2","100.2","11.2","0.2","2.2"};
    ranges::for_each(strings, [](const auto& str) { std::cout << str << std::endl; });
    
    strings | ranges::views::all | ranges::actions::sort;
    
    std::cout << std::endl;
    ranges::for_each(strings, [](const auto& str) { std::cout << str << std::endl; });

    return 0;
}

假设我希望在排序之前将字符串转换为双精度。使用函数式方法,这是可能的:

strings |= ranges::actions::sort(std::less{}, [](const auto& str) { return std::stod(str); });

但是我想知道是否有一种管道格式允许这样做,它将这个投影应用于所有以下操作,例如:

strings | ranges::views::projection([](const auto&str ) { return std::stod(str); }) | ranges::actions::sort;

请注意, usingranges::views::transform不起作用,因为它会创建一个新范围而不是投影。

我也不确定range-v3 文档中是否推荐使用strings | ranges::views::all | ranges::actions::sort而不是使用警告。strings |= ranges::actions::sort

4

1 回答 1

1

更新(2021.01.26):

对投影视图执行操作可能会导致混淆。例如,想象一个带有签名的投影函数,int&(std::pair<int, int>&) / int&&(std::pair<int, int>&&)它返回一对中的第一个分量,将该投影应用于std::pair<int, int>. 如果我们应该filter怎么办?

  • 它应该返回一个范围,int因为我们向它传递了一个范围int
  • 它还应该返回一个范围,std::pair<int, int>因为我们真的想过滤 的基础范围std::pair<int, int>

但它不知道我们想要哪个。

因此,这次似乎不适合将投影视为对范围的独立操作,而是更清楚投影操作是否是过滤器或排序的可选参数。


旧答案(2021.01.15):

使用投影实现排序效率低下,也许这就是没有提供它的原因。您必须明确存储投影结果:
c++ - 为什么不能在 range-v3 中对范围进行排序?- Stack Overflow
为什么不能在 range-v3 中对范围进行排序?

标准版本表示投影的复杂度为 (N·log(N)) (因此在排序之前投影元素并存储它们可能会更快):
std::ranges::sort - cppreference.com
https://en .cppreference.com/w/cpp/algorithm/ranges/sort

于 2021-01-15T03:19:58.000 回答