Search code examples
c++new-operatorplacement-new

Placement new vs assignment in STL implementation


I've been curiously inspecting STL's implementation and found this code in experimental/optional. Here's the code:

optional&
operator=(const optional& __opt)
{
    if (this->__engaged_ == __opt.__engaged_)
    {
        if (this->__engaged_)
            this->__val_ = __opt.__val_;
    }
    else
    {
        if (this->__engaged_)
            this->__val_.~value_type();
        else
            ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
        this->__engaged_ = __opt.__engaged_;
    }
    return *this;
}

This is the copy assignment operator implementation for the std::optional<T> class. I believe that for effects of this discussion, it should also be important to make it clear what those variables are, so here's the classe's storage:

typedef _Tp value_type;
union
{
    char __null_state_;
    value_type __val_;
};
bool __engaged_ = false;

The first code excerpt shows assignments to __val_ in two different ways, one using a simple assignment (this->__val_ = __opt.__val_) and the other using placement new (::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);). What's the difference? Why use one or another, in this case?


Solution

  • The storage inside an optional is not initialized by default. In the first case, the storage has already been constructed so it uses the object's copy assignment operator.

    In the second case it needs to construct an object into the allocated storage because in that code path the lefthand side of the assignment has never had its storage constructed..