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: