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.

Reply via email to