C++ Logo


Advanced search

Re: [std-proposals] Add operator>> overloads to std::optional for streaming input

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Sun, 25 Jun 2023 00:21:29 +0100
On Sat, 24 Jun 2023, 23:38 Kevin Schmidt via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> Hello everybody, I would like to propose the following for the new
> standard:
> Motivation:
> Currently, std::optional does not have an operator>> defined, so values
> cannot be streamed directly into an std::optional. Users have to explicitly
> extract the value from the stream and assign it to the std::optional using
> emplace() or operator=(). By adding operator>> overloads, std::optional can
> support more intuitive streaming input.
> Initial Design Proposition:
> template <typename T>
> std::istream& operator>>(std::istream& is, std::optional<T>& opt) {
> T value;
> if (is >> value) {
> opt.emplace(value);
> } else {
> opt.reset();
> }
> return is;
> }

I think the proposal should explain/discuss why that is better than:

if (opt)
  is >> *opt;
else {
  T val;
  if (is >> val)

i.e. why should it change the state of the optional if reading from the
stream fails? Why should it always emplace a new object even if the
optional already contains a value?

> This defines an operator>> that extracts a value of type T from the input
> stream "is" and assigns it to the std::optional<T> object "opt". If the
> extraction succeeds, the value is emplace()d into "opt". If it fails, "opt"
> is reset to an empty state. This is just a basic implementation that can be
> used without the internals. For the implementation into the standard I
> would suggest a rewrite using the internals of std::optional to overcome
> the issue of using one unnecessary stack allocation.


I still believe that mentioning this is important though since this code
> can be used as a premature implementation for now.
> The implementation allows code like:
> std::optional<int> opt;
> std::istringstream("123") >> opt;
> // opt is 123
> Impact on the Standard:
> This change will make std::optional more intuitive to use for streaming
> input, as values can be extracted directly into an optional without needing
> to handle the empty case explicitly. It brings std::optional inline with
> other wrapper types like std::variant that support streaming through
> operator>> overloads.

Unless I'm mistaken, you can't stream into a variant. You can only stream
into an already active alternative. Which is similar to optional, where you
can only stream into a contained value (not into a disengaged optional).

> The proposed changes are limited to overloads for std::istream and its
> derived types. Overloads for other stream types can be added separately.

What other stream types do you mean?

The proposed design is limited to a single-argument overload to avoid
> ambiguity, but additional overloads can be defined if needed.
> This change should have limited impact on existing code, as it purely adds
> additional functionality. The proposed design has been kept simple, but can
> be extended in the future if needed.
> I hope that this fits nicely into the standard, any feedback or
> improvement suggestions are welcome.
> Thanks for your attention,
> Kevin
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-06-24 23:21:44