@@ -56,7 +56,7 @@ class optional_t {
5656 static_assert (!std::is_const<T>::value, " " );
5757 static_assert (!std::is_volatile<T>::value, " " );
5858
59- optional_t (const nullopt_t nullopt_ ) : has_value_(false ), dummy {} {}
59+ optional_t (const nullopt_t ) : has_value_(false ), dummy {} {}
6060 optional_t () : optional_t (nullopt ) {}
6161 optional_t (const T &object) : has_value_(true ), value_(object) {}
6262 optional_t (const optional_t &other)
@@ -71,22 +71,26 @@ class optional_t {
7171 if (has_value_) value_.~T ();
7272 }
7373
74- optional_t &operator =(const nullopt_t nullopt_ ) {
74+ optional_t &operator =(const nullopt_t ) {
7575 if (has_value_) value_.~T ();
7676 has_value_ = false ;
77+ return *this ;
7778 }
7879 optional_t &operator =(const optional_t &other) {
7980 if (this == &other) return *this ;
8081 if (has_value_) value_.~T ();
8182 has_value_ = other.has_value_ ;
82- if (has_value_) value_ = other.value_ ;
83+ // Placement-new construct: value_ is not a living object here (either
84+ // it was just destroyed above or it was never constructed), so we must
85+ // construct it rather than assign to it.
86+ if (has_value_) new (std::addressof (value_)) T (other.value_ );
8387 return *this ;
8488 }
8589 optional_t &operator =(optional_t &&other) {
8690 if (this == &other) return *this ;
8791 if (has_value_) value_.~T ();
8892 has_value_ = other.has_value_ ;
89- if (has_value_) value_ = std::move (other.value_ );
93+ if (has_value_) new ( std::addressof ( value_)) T ( std::move (other.value_ ) );
9094 return *this ;
9195 }
9296
0 commit comments