Home > front end >  Does c 20 ranges have any view functions that do not return value?
Does c 20 ranges have any view functions that do not return value?

Time:08-02

I can use std::views::transform to create new stream-style containers and then prints it, like this:

#include<iostream>
#include<vector>
#include<ranges>
using namespace std;
int main() {
    // clang -std=c  20
    std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    auto output = input 
        | std::views::filter([](const int n) {return n % 3 == 0; })
        | std::views::transform([](const int n) {return n * n; });
    for (auto o : output) {
        cout << o << endl;
    }
    return 0;
}

Yes, it works, but I wish to simply my for loop to write it into the pipelines connected by |, is there a way to change the code to be like:

input 
        | std::views::filter([](const int n) {return n % 3 == 0; })
        | std::views::transform([](const int n) {return n * n; })
        | std::views::SOME_FUNCTION(cout<<n<<endl);

which avoids my for loop.

So my question is: does std::views has SOME_FUNCTION that could fulfill my needs?

CodePudding user response:

What you are looking for is not a view. Actually I am not entirely sure what you are looking for, but perhaps it is std::ranges::for_each:

#include<iostream>
#include<vector>
#include<ranges>
#include <algorithm>
using namespace std;
int main() {
    // clang -std=c  20
    std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
    std::ranges::for_each(input 
        | std::views::filter([](const int n) {return n % 3 == 0; })
        | std::views::transform([](const int n) {return n * n; }),
        [](auto x){std::cout << x << endl;});
}

CodePudding user response:

There is no such adaptor in C 20 (or C 23). I also find this feature missing, since it would enable programmers to shift towards more consistent and more "pure" functional style, rather than composing an expression via pipes (|) and then using it in a loop.

Ultimately, I would like to have std::views::for_each (or maybe std::actions::for_each, if actions make it to the standard) that would do exactly that. As of right now, you could implement you own for_each that's pipeable, but unfortunately, that woulnd't be as standard as one would like.

So for now the safest thing is to stick to either a range-based for loop or to std::ranges::for_each.

  • Related