To me, std::optional<T> always was a "cleaner" version of std::unique_ptr<T>: both have an empty state (optional() and nullptr) and own a T object otherwise. This analogy, however, breaks down when considering std::optional<const T>. The first code block is valid, while the second one should not be, as the type (const T) needs to be MoveAssignable.
std::unique_ptr<const int> ptr1, ptr2; ptr1 = std::move(ptr2); std::optional<const int> opt1, opt2; opt1 = std::move(opt2); With a similar reasoning, I would expect std::optional<T&> to be equivalent to a non-owning pointer T*. While this analogy is a bit blurry for general T, I think it would make much sense for const T.
const int ZERO = 0; void AssignPtrIfNull(const int*& ptr) { ptr = (ptr == nullptr ? &ZERO : ptr); } void AssignOptIfNull(std::optional<const int&>& ptr) { ptr = (ptr ? make_optional<const int&>(ZERO) : ptr); } So I am wondering, what is the thought process behind making optional the way it is? Because it seems really odd to me. Are there some pitfalls I am overseeing?
std::optionalwithstd::unique_ptras they are different beasts?std::optional's ancestorboost::optional. They are quite close in spirit, despite the standard type having some small changes.