On Saturday, 24 July 2021 at 18:10:07 UTC, Alexey wrote:
The goal I with to achieve by this check - is to use template
and to assign value to variable basing on it's ability to
accept null as a value.
The most direct representation of that is __traits(compiles, (T
t) { t = null; });
Another cool trick to consider is:
is(typeof(null) : Whatever)
What that means is if the null literal will implicitly convert to
Whatever type. This means you can pass `null` as an argument to a
function accepting Whatever. Thus it includes pointers, classes,
interfaces, arrays. But does NOT include structs, even if they
have a null accepting constructor / opAssign since you still must
explicitly construct them.
struct S {
void opAssign(typeof(null) n) {}
}
void main() {
S s;
s = null; // allowed due to opAssign
}
pragma(msg, is(typeof(null) : S)); // FALSE because this check
only looks for implicit conversion, not user-defined assign
overloads or constructors.
The traits compiles check will allow this, since it is looking at
assign... but the traits compiles will say false if it gets a
`const` type since obviously then assign is not allowed, even if
implicit conversion would be.
Depending on your needs you might use one of these, or perhaps
both.