On Sat, 24 Jun 2023, 23:38 Kevin Schmidt via Std-Proposals, <std-proposals@lists.isocpp.org> wrote:
Hello everybody, I would like to propose the following for the new standard:


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) {
    } else {
    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,
Std-Proposals mailing list