19

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?

0

1 Answer 1

21

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

Sign up to request clarification or add additional context in comments.

3 Comments

How can I define what type the values in the range shall have? What does the "auto" do there? This syntax looks weird?
@Mr.Clear If you want to constrain it further than it already is, you could use require or make a concept that combines input_range and the set of types you want to approve it for. auto is there because it's required for this kind of usage of type-constraints. Weird syntax? C++20 gave us some news for sure but I don't think it's that weird.
One possible reason why there isn't a specific input_range<T> is explained in stackoverflow.com/a/64228354/5267751

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.