Date
2016-08-08.00:00:00
Message id
8448

Content

[ 2016-08-08 Ville reopens and provides improved wording ]

This alternative proposed wording also resolves 2753.

The constructors that take a const T& or T&& are replaced by a constructor template that takes a U&& and defaults U = T. This allows copy-list-initialization with empty braces to still work:

optional<whatever> o = {}; // equivalent to initializing optional with nullopt

This resolution makes converting constructors and assignments have the same capabilities, including using arguments that can't be deduced. That is achieved by using a perfect-forwarding constructor and an assignment operator that default their argument to T. We don't need separate overloads for T, the overload for U does the job:

optional<vector<int>> ovi{{1, 2, 3}}; // still works
ovi = {4, 5, 6, 7}; // now works, didn't work before

Furthermore, this proposed wording makes optional "always unwrap". That is, the result of the following initializations is the same:

optional<optional<int>> oi = optional<int>();
optional<optional<int>> oi = optional<short>();

Both of those initializations initialize the optional wrapping another optional as if initializing with nullopt. Assignments do the same. These changes solve the issues pointed out by Tomasz Kami&nacute;ski.

This P/R has been implemented and tested as a modification on top of libstdc++'s optional.