C++ Logo

std-proposals

Advanced search

Re: A 'stream()' member for std::ostream_iterator and cousins

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 31 Jan 2021 17:55:03 -0500
On Sun, Jan 31, 2021 at 11:25 AM Marco Fantozzi via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> std::string print_vector( const std::vector<int> & v ) {
> std::stringstream s;
> copy( begin(v), end(v), std::ostream_iterator<int>( s, ", " ) );
> return s.str();
> }
>
> If there was a method ostream_iterator<...>::stream() that returns the
> reference to the stream captured by the iterator,
> it would be possible to make the above code more concise:
>
> template<typename T>
> std::string print_vector( const vector<T> & v )
> {
> return copy( begin(v), end(v), ostream_iterator<int>( stringstream{},
> ", " ) ).stream().str();
> }
>

Sadly this won't work, for the same reason that it's already impossible to
write

template<class T>
std::string print_item(const T& t) {
    std::ostringstream oss;
    return (oss << t).str();
}

The result of `operator<<` is `ostream&`, not `ostringstream&`, and
`ostream` hasn't got a `.str()` method.
The result of `ostream_iterator<int>::stream()` would likewise have to be
`ostream&`, not `ostringstream&`.

You can do it if you redesign `ostream_iterator<StreamType, ValueType>` to
be a much more templatey animal, more C++20 Ranges-style; but then you're
not talking about a minor tweak to `std::ostream_iterator` anymore.

–Arthur

Received on 2021-01-31 16:55:18