CW Holeman II
CW Holeman II

Reputation: 4961

Writing a C++20 range to standard output

I can take several ints from a vector putting them to standard output with an iterator:

std::vector<int> v{0,1,2,3,4,5};
std::copy_n(v.begin(),
    3,
    std::ostream_iterator<int>(std::cout, ":"));

I can use the new C++20 ranges to take several ints from a vector putting them to standard output with | operator in a for loop, one value at a time using <<.

for(int n : std::views::all(v)
    | std::views::take(3))
{
    std::cout << n << '/';
}

How can I put the results of std::views::all(v) | std::views::take(3) to standard output w/o explicitly looping through values?

Something like:

std::views::all(v)
    | std::views::take(4)
    | std::ostream_iterator<int>(std::cout, " ");

or

std::cout << (std::views::all(v)
    | std::views::take(4));

Upvotes: 3

Views: 1604

Answers (1)

Barry
Barry

Reputation: 302758

The specific thing you're looking for is using the new ranges algorithms:

std::ranges::copy(v | std::views::take(4),
        std::ostream_iterator<int>(std::cout, " "));

You don't need to use views::all directly, the above is sufficient.

You can also use fmtlib, either directly:

// with <fmt/ranges.h>
// this prints {0, 1, 2, 3}
fmt::print("{}\n", v | std::views::take(4));

or using fmt::join to get more control (this lets you apply a format string to each element in addition to specifying the delimiter):

// this prints [00:01:02:03]
fmt::print("[{:02x}]\n", fmt::join(v | std::views::take(4), ":"));

Upvotes: 7

Related Questions