'how do you destroy the value of a trivially destructible type within a disengaged trivially destructible sum type
A sum type such as std::optional is implemented with conditionally trivial member functions because the template parameter may have a non trivial destructor. It's destructor is thus implemented as follows:
~optional()
{
if (bool(*this))
{
payload.~T();
}
}
~optional() requires std::is_trivially_destructible_v<T> = default;
And to express a disengaged state we write:
constexpr optional& operator = (nullopt_t) noexcept
{
if (bool(*this))
{
payload.~stored_type();
engaged = false;
}
return *this;
}
But what if our sum type's template parameter is restricted to being trivially destructible...
template <std::integral T>
class trivial_sum_type;
How do we ensure, for instance within a swap member function, that when we exchange values from an engaged to a disengaged object that the destructor for the value within the previously engaged object is called? And vice versa
template <std::integral T>
class trivial_sum_type
{
//everything else same as std::optional except it is restriced to a trivial type i.e std::integral
constexpr void swap(const trivial_sum_type& rhs)
{
if (bool(*this) and bool(rhs))
{
std::swap(payload, *rhs);
}
else if (bool(*this) and not bool(rhs))
{
new(std::addressof(payload))stored_type(std::move(payload));
payload.~stored_type(); //what if stored_type is an int
}
else if (not bool(*this) and bool(rhs))
{
new(std::addressof(payload))stored_type(std::move(*rhs));
rhs.payload.~stored_type(); //same issue here
}
}
~trivial_sum_type() = default;
private:
struct empty_byte{};
union
{
T payload;
empty_byte empty;
}
bool engaged;
}
My confusion is here: you do not explicitly write a destructor for a trivially destructible type within the sum type's destructor function, but does it also mean that when you swap or express a disengaged state you should not call a destructor on such types. Which leads me to the question do trivial types have destructors? And how do you destroy the value of a trivially destructible type within a disengaged trivially destructible sum type? Hopefully...am not stack raving mad and my lack of understanding makes sense
Solution 1:[1]
I interpret the question as asking for payload.~stored_type(); when the stored_type is int or some other fundamental type that does not have a destructor. A type that is trivially destructible is not exactly that, it may have a destructor (that is not user provided, not virtual and all base classes and non-static members have trivial destructors, see https://en.cppreference.com/w/cpp/language/destructor#Trivial_destructor).
In simple words, a trivial destructor is a destructor that does nothing. It can be called but its not an issue when it is not called. Your question seems to be about types that do not have a destructor.
For such cases (when there is no destructor to be called) there are pseudo destructors (https://en.cppreference.com/w/cpp/language/destructor):
In generic contexts, the destructor call syntax can be used with an object of non-class type; this is known as pseudo-destructor call: see member access operator.
For example, consider the following, which calls the int pseudo-destructor (and then leaks the memory):
template <typename T>
void foo() {
T* x = new T;
(*x).~T(); // no issue, int has a pseudo destructor
}
int main()
{
foo<int>();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | 463035818_is_not_a_number |
