C++ quick tips: What are conditional special member functions in C++20?
Introduction of concepts in c++20 brought along a new set of problems requiring
solving related to wrapper types (like e.g. std::optional
, std::variant
).
Specifically, special functions (like constructors, copy constructors, destructors etc) need to have the same type of traits as the type they are wrapping i.e. these have to be copyable if the underlying type is copyable, trivially copyable if the underlying types are trivially copyable, and trivially destructible if the underlying types are trivially destructible.
That led to an introduction of a, not so well known feature in c++20, that allows special function overloading.
Template type specialisation and special functions overloading
Consider this example code:
|
|
I could extract the constructor and the data member to a common base to minimise duplication but with C++20 there’s a better way:
|
|
But that’s not all. Type constraints and function overloading can be applied to special functions as well!
|
|
This feature was introduced with
p0848 (later revised as p0847r3)
and allows solving problems with std::optional
and friends - the underlying
wrapped type’s special function traits are now easily propagated to wrappers
without excess class template specialisations.
New wording
The new revision introduces an important term prospective destructor and prospective special member function.
In simplest terms, in my understanding, any prospective special member function (including a destructor) is a non-deleted function with defined and satisfied constraints. In case of destructors, there’s an extra stipulation that there can be only one eligible destructor with satisfied constraints.
Exact definition for each function type is described in the rev 1 of the proposal.