Reputation: 4961
I can read int
s from standard input, transforming them into odd
or even
, writing the results to standard output:
std::vector<int> v;
std::ranges::copy(
std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(v)
);
std::ranges::copy(
v | std::views::transform([](int a_int){return a_int%2 ? "odd":"even";}),
std::ostream_iterator<std::string>(std::cout, " ")
);
which can be done w/o temporary variables:
std::transform(
std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::ostream_iterator<std::string>(std::cout, " "),
[](int a_int){return a_int%2 ? "odd":"even";});
How do I use C++20 Range adaptors to do this w/o the temps?
Something more like:
std::istream_iterator<int>(std::cin)
| std::transform([](int a_int){return a_int%2 ? "odd":"even";})
| std::ostream_iterator<std::string>(std::cout, " ");
Upvotes: 1
Views: 273
Reputation: 40791
You can always turn an iterator based algorithm into a view based one with std::ranges::subrange
:
std::ranges::copy(
std::ranges::subrange(std::istream_iterator<int>(std::cin), std::istream_iterator<int>())
| std::views::transform([](int a_int){return a_int%2 ? "odd":"even";}),
std::ostream_iterator<const char*>(std::cout, " ")
);
Though in this case there is a specialised std::ranges::istream_view<T>
, which is essentially equivalent to the subrange:
std::ranges::copy(
std::ranges::istream_view<int>(std::cin)
| std::views::transform([](int a_int){return a_int%2 ? "odd":"even";}),
std::ostream_iterator<const char*>(std::cout, " ")
);
Upvotes: 3