Reputation: 2399
To the internal content of an optional, doesn't the optional require placement new in order to reconstruct the internal in place storage or union? Is there some new feature like placement new in C++ 20 that allows for constexpr assignment of std::optional?
template< class U = T >
optional& operator=( U&& value );
(since C++17)
(until C++20)
template< class U = T >
constexpr optional& operator=( U&& value );
(since C++20)
Upvotes: 13
Views: 589
Reputation: 302852
To the internal content of an optional, doesn't the optional require placement new in order to reconstruct the internal in place storage or union?
For assignment, yes it does.
But while we still cannot do actual placement new during constexpr time, we did get a workaround for its absence: std::construct_at
(from P0784). This is a very limited form of placement new, but it's enough to get optional
assignment working.
The other change was that we also needed to be able to actually change the active member of a union - since it wouldn't matter if we could construct the new object if we couldn't actually switch. That also happened in C++20 (P1330).
Put those together, and you get a functional implementation of optional assignment: P2231. An abbreviated implementation would look like this:
template <typename T>
struct optional {
union {
T value;
char empty;
};
bool has_value;
constexpr optional& operator=(T const& rhs) {
if (has_value) {
value = rhs;
} else {
// basically ::new (&value) T(rhs);
// except blessed for constexpr usage
std::construct_at(&value, rhs);
}
has_value = true;
return *this;
}
};
Upvotes: 10