Date: Sat, 07 Jun 2025 12:33:28 +0300
Consider std::optional<T>.
The move constructor has to check if the moved-from optional is
engaged, and if so, move-construct the contained T. Similarly other
special functions have to take actions conditionally. The destructor
has to check if the optional is engaged and only invoke T::~T() if
that's the case.
However, if we had a way to cheaply create a T, we could use that and
avoid all the conditionals. Let's say the protocol is
template <typename T>
struct construct_empty {};
template <>
struct construct_empty<my_lovely_type> {
static void operator()(my_lovely_type* where) noexcept;
};
If construct_empty is specialized for a T, then optional<T>'s default
constructor could initialize the contained T whether or not the
optional is engaged or not, and all the conditionals for the special
methods would disappear. For trivially constructible standard types,
construct_empty would do nothing. For many standard types, we could
call the default constructor. The user could opt-in for cheaply
constructible user types, often just calling the default constructor.
This seems related to trivial relocation, just from the other side as
it were. Maybe opt-in should also be via an attribute.
The move constructor has to check if the moved-from optional is
engaged, and if so, move-construct the contained T. Similarly other
special functions have to take actions conditionally. The destructor
has to check if the optional is engaged and only invoke T::~T() if
that's the case.
However, if we had a way to cheaply create a T, we could use that and
avoid all the conditionals. Let's say the protocol is
template <typename T>
struct construct_empty {};
template <>
struct construct_empty<my_lovely_type> {
static void operator()(my_lovely_type* where) noexcept;
};
If construct_empty is specialized for a T, then optional<T>'s default
constructor could initialize the contained T whether or not the
optional is engaged or not, and all the conditionals for the special
methods would disappear. For trivially constructible standard types,
construct_empty would do nothing. For many standard types, we could
call the default constructor. The user could opt-in for cheaply
constructible user types, often just calling the default constructor.
This seems related to trivial relocation, just from the other side as
it were. Maybe opt-in should also be via an attribute.
Received on 2025-06-07 09:33:49