4

In range-v3, is there a more efficient way (less steps, cleaner, more expressive, more elegant, more performant, ...) to create a view by selecting elements of a range by arbitrary indexes of the range than using views::counted plus views::concat as in

auto v = std::vector<int> {6,7,8,9,10,11};
auto v1 = views::counted(ranges::begin(v) + 1, 1); // [7]
auto v2 = views::counted(ranges::begin(v) + 3, 1); // [9]
auto v3 = views::counted(ranges::begin(v) + 4, 1); // [10]
auto vFinal = views::concat(v1,v2,v3); // [7,9,10]
Porsche9II
  • 629
  • 5
  • 17
yannick
  • 95
  • 6

1 Answers1

2

You can wrap up the calls to ranges::views::concat by putting the indices in a range, and calling ranges::views::for_each which maps each element to a function returning a range, then concatenates everything.

auto v = std::vector<int>{6,7,8,9,10,11};
auto i = std::vector<int>{1,3,4};
auto vFinal = i
    | ranges::views::for_each([&v](auto i) { return v | ranges::views::slice(i, i+1); });

https://godbolt.org/z/Wocb8W

parktomatomi
  • 3,851
  • 1
  • 14
  • 18
  • Using `std::vector` allocates memory on the heap, which is unnecessary if the list is fixed at compile time. initializer_list or std::array< might be better. – user202729 Oct 05 '20 at 11:45
  • @user202729 Thanks for the feedback, that's absolutely correct! Just want to match the convention in the question :) – parktomatomi Oct 05 '20 at 14:12