Implicit conversion in constructor
Adam D. Ruppe via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Jul 17 19:56:21 PDT 2015
On Saturday, 18 July 2015 at 02:23:26 UTC, rcorre wrote:
> Is there any reason why implicit conversion from Foo to Thing
> is permitted in a regular method but not in a constructor?
In the constructor, you are supposed to be constructing things,
so the first "assignment" of structs is actually a constructor
call. D does not support implicit construction (kinda sadly, but
it doesn't).
In the other methods, it calls opAssign instead, since the struct
already exists. So this is the difference between:
Thing thing = new Foo(); // in the ctor, this line in main
wouldn't work either with the same error
and
thing = new Foo(); // in the other method, this line in main does
work
Try adding `void opAssign(T)(T t) { static assert(0); }` to your
struct and recompile. You'll see it throws on the method. Then
change that `opAssign` to `this`, so it becomes a constructor.
Then you'll see it is called in the class constructor.
Moreover, note that this only applies to the *first* assignment
of the struct. If you copy/paste that line in the constructor
again right under it, you'll see the compiler only throws the
error once. The first one is a construction. The second one is a
standard assignment again.
Put those two lines in a runtime branch: `if(something) thing =
new Foo(); else thing = new Foo();` and notice how the compiler
throws two errors again.
The first assignment in any branch of a constructor is a
construction! The next one is an assignment.
So the rule is slightly complex (and the implementation may be
buggy, though it seems good to me now), but it is intentional.
The reason for this goes beyond just that constructors are
supposed to be constructing. It also is relevant for `immutable`
members - these are allowed to be constructed, but not modified,
so if the class constructor didn't treat those as constructions,
it would be impossible to set them up with runtime data.
And it is also important for `@disable this()` struct members,
which must be constructed explicitly. If the first assignment in
a ctor didn't count for that, you couldn't have them in a class
at all.
More information about the Digitalmars-d-learn
mailing list