4

I want to loop through a vector in a sorted way without modifying the underlying vector.

Can std::views and/or std::range be used for this purpose?

I've successfully implemented filtering using views, but I don't know if it is possible to sort using a predicate.

You can find an example to complete here : https://godbolt.org/z/cKer8frvq

#include <iostream>
#include <ranges>
#include <vector>
#include <chrono>

struct Data{
    int a;
};

int main() {

    std::vector<Data> vec = {{1}, {2}, {3}, {10}, {5}, {6}};
  
    auto sortedView = // <= can we use std::views here ?
                           
    for (const auto &sortedData: sortedView) std::cout << std::to_string(sortedData.a) << std::endl; // 1 2 3 5 6 10

    for (const auto &data: vec) std::cout << std::to_string(data.a) << std::endl; // 1 2 3 10 5 6
}
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
Victor
  • 133
  • 7

1 Answers1

6

You have to modify something to use std::ranges::sort (or std::sort), but it doesn't have to be your actual data.

#include <iostream>
#include <ranges>
#include <numeric>
#include <algorithm>
#include <vector>
#include <chrono>

struct Data{
    int a;
    friend auto operator<=> (const Data &, const Data &) = default;
};

int main() {

    std::vector<Data> vec = {{1}, {2}, {3}, {10}, {5}, {6}};

    std::vector<std::size_t> indexes(vec.size());
    std::iota(indexes.begin(), indexes.end(), std::size_t{ 0 }); // 0z in C++23

    auto proj = [&vec](std::size_t i) -> Data & { return vec[i]; };

    std::ranges::sort(indexes, std::less<>{}, proj);
  
    auto sortedView = std::ranges::views::transform(indexes, proj);
                           
    for (const auto &sortedData: sortedView) std::cout << sortedData.a << std::endl; // 1 2 3 5 6 10

    for (const auto &data: vec) std::cout << data.a << std::endl; // 1 2 3 10 5 6
}
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • Can you explain this line in detail please? : `auto proj = [&vec](std::size_t i) -> Data & { return vec[i]; };` – Victor Mar 07 '22 at 07:05
  • @Victor: See [lambda](https://en.cppreference.com/w/cpp/language/lambda) (with capture and trailling return type). – Jarod42 Mar 07 '22 at 12:05
  • @Jarod42 it's actually the `Data & { return vec[i]; }` return type that I don't understand right now – Victor Mar 07 '22 at 12:35
  • @Victor: `-> Data&` is trailing return type. (without that it would return by value). – Jarod42 Mar 07 '22 at 14:06