Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing std::ranges::views as parameters in C++20

I have a method that prints a list of integers (my actual method is a bit more complicated but it is also read-only):

void printElements(const std::vector<int> &integersList)
{
    std::for_each(integersList.begin(), integersList.end(), [](const auto& e){
        std::cout << e << "\n";
    });
}

Now suppose I have the following vector:

std::vector<int> vec{1,2,3,4,5,6,7,8,9,10};

Then I want to print even numbers only. To do this, I thought of employing the new std::ranges feature in C++20. I know that you can do this as follows:

auto evenList = vec | std::views::filter([](auto i){ return i % 2 == 0; });

Now I would like to call printElements(evenList), however this obviously won't compile. What would be the solution to this? Also can I write a single function that will both print a std::vector and an object of the same type as my evenList? Or do I need to write two separate functions?

like image 956
mathripper Avatar asked Dec 04 '25 08:12

mathripper


1 Answers

You can make printElements take any object by making it a function template. This will instantiate it for views as well as vectors.

#include <algorithm>
#include <iostream>
#include <ranges>

void printElements(std::ranges::input_range auto&& range) {
    std::ranges::for_each(range, [](const auto& e) { std::cout << e << '\n'; });
}

Demo

or:

// ...
#include <iterator>

void printElements(std::ranges::input_range auto&& range) {
    using T = std::ranges::range_value_t<decltype(range)>;
    std::ranges::copy(range, std::ostream_iterator<T>(std::cout, "\n"));
}

Demo

like image 56
Ted Lyngmo Avatar answered Dec 07 '25 00:12

Ted Lyngmo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!