On Friday, 16 September 2022 at 22:43:43 UTC, frame wrote:
> import std.variant;
// error: destructor `std.variant.VariantN!32LU.VariantN.~this` is not `nothrow`
void fun(Variant v) nothrow
{
}
void main()
{
fun(Variant());
}
A reference, pointer or slice works. I could do something on the caller site but the signature of fun()
should remain like above.
A reference effectively is a never-null
pointer. A slice is a pointer to the first of many objects plus the number of those objects (or empty, or null
).
It boils down to pointers, and the pointed-to Variant
object is not the responsibility of fun
.
When you have a parameter that binds by copy, you cannot escape from calling its destructor, and if one happens not to be nothrow
, your function cannot be nothrow
.
The new semantics for in
(compile with -preview=in
) might work for you. The in
storage class binds by copy if the copy is cheap – which I suspect is never the case for a Variant
– or else by reference; and it can bind temporaries by reference (unlike ref
). However, in
also incurs const
and scope
. It is unlikely that scope
will be your problem, but const
very well might be an issue when the contained value has indirections to mutable values, e.g. an int[]
will be read as a const(int)[]
.
Calling the destructor is then the responsibility of the caller.
// Compile with -preview=in
import std.variant;
void fun(in Variant v) nothrow { }
void main()
{
fun(Variant()); // okay: `in` binds rvalues
Variant v;
fun(v); // okay: `in` binds lvalues
}