8

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?

mathripper
  • 299
  • 1
  • 12

1 Answers1

14

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

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108