c++20 why can't I "pipe" into views::reverse like the other views functions?

Viewed 85

I am testing some of the fancy new c++ features, one of which is ranges and the associated views. I find it particularly interesting that you can chain what you wish to do with a container.

You can use the binary operator|() to chain things, which is really nice. I noticed that you can chain into std::views::take(int), std::views::transform() with a lambda or function pointer, std::views::filter() with a lambda or function pointer. The only thing you can't use is std::views::reverse. That one can only be used by putting a range into it's argument. Why it that? Is there an alternative?

#include <iostream>
#include <vector>
#include <string>
#include <ranges>

int main()
{
  using std::string;
  using std::cout, std::endl;
  
  const std::vector<string> vec = { "A", "B", "a", "b", "b2", "a2", "a3", "b3", "b4" };
  
  for (auto const& val : std::views::reverse(vec) // ok
                      | std::views::take_while([](const string& s) {return s.size() > 0 && s[0] == 'b'; })
                      // | std::views::reverse() // Error?!
    )
  {
    cout << val << endl;
  }
}

Compile with g++ -std=c++20 main.cpp -o main How would I get b3, b4 in that situation using the syntax above?

1 Answers

The syntax for piping into single-argument adaptors isn't:

| views::reverse()

It's

| views::reverse

No parentheses in this case. std::views::reverse(a) could be written as a | std::views::reverse to start with as well.

Similar for all the other single-argument range adaptors (join, keys, values, elements<N>, etc.).

Related