Why std::optional (std::experimental::optional in libc++ at the moment) does not have specialization for reference types (compared
The main problem with std::optional is — what should optRef = obj do in the following case:
optional optRef;
…;
T obj {…};
optRef = obj; // <-- here!
Variants:
(&optRef)->~optional(); new (&optRef) optional(obj) .*optRef = obj (UB when !optRef before).if (optRef) {do1;} else {do2;}.Pros of every variant:
Always rebind (chosen by boost::optional and n1878):
!optRef and optRef.has_value() — post-condition &*optRef == &obj is always met.optional in the following aspect: for usual optional, if T::operator= is defined to act as destroying and constructing (and some argue that it must be nothing more than optimization for destroying-and-constructing), opt = … de facto acts similarly like (&opt)->~optional(); new (&opt) optional(obj) .Assign through:
T& in the following aspect: for pure T&, ref = … assigns through (not rebinds the ref).optional in the following aspect: for usual optional, when opt.has_value(), opt = … is required to assign through, not to destroy-and-construct (see template optional& optional::operator=(U&& v) in n3672 and on cppreference.com).optional in the following aspect: both haveoperator= defined at least somehow.Bind if empty, assign through otherwise — I see no real benefits, IMHO this variant arises only when proponents of #1 argue with proponents of #2, however formally it's even more consistent with the letter of requirements for template (but not with the spirit, IMHO).
No assignment operator (chosen by n3406):
T& in the following aspect: pure T& doesn't allow to rebind itself.See also: