If I move-construct a from b, is it still necessary to destruct b, or can I get away without doing so?
This question crossed my mind during the implementation of an optional<T> template. Excerpt:
~optional()
{
if (initialized)
{
reinterpret_cast<T*>(data)->~T();
}
}
optional(optional&& o) : initialized(o.initialized)
{
if (initialized)
{
new(data) T(std::move(*o)); // move from o.data
o.initialized = false; // o.data won't be destructed anymore!
}
}
Of course, I could just replace the bool initialized with a three-valued enumeration that distinguishes between initialized, non-initialized and moved-from. I just want to know if this is strictly necessary.
Yes, it is still necessary to destruct
b. A moved from object is a valid, constructed object. In some cases, it may even hold resources that still need to be disposed of. In generic code such as you show,Tmay not even have a move constructor. You may invoke a copy constructor instead in this case. So you can definitely not assume that ~T() is a no-op and can be elided.