CW Holeman II
CW Holeman II

Reputation: 4961

Standard input to C++20 range adaptors w/o temporary variables

I can read ints 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

Answers (1)

Artyer
Artyer

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

Related Questions