digitalmars.D - alias this constructor
- Dave Jones (9/9) Mar 24 2018 struct Foo
- Jonathan M Davis (16/25) Mar 24 2018 Because it was deemed to cause too many problems. C++ code can have quit...
- Shachar Shemesh (18/37) Mar 24 2018 That's a good reason to disallow assignment from int to Foo. I see zero
- Jonathan M Davis (13/51) Mar 24 2018 Having something like opImplicitCast would arguably have been better tha...
- Adam D. Ruppe (14/22) Mar 24 2018 You just need to define a constructor that takes an int. alias
struct Foo { int x; alias x this; } Foo f = 12; // error Foo foo; f = 12; // this is OK any reason why the first cant be allowed?
Mar 24 2018
On Sunday, March 25, 2018 00:47:20 Dave Jones via Digitalmars-d wrote:struct Foo { int x; alias x this; } Foo f = 12; // error Foo foo; f = 12; // this is OK any reason why the first cant be allowed?Because it was deemed to cause too many problems. C++ code can have quite a few problems related to all of the implicit conversions it allows with stuff like constructing objects. Walter decided that D would be better off if it did not allow such conversions, and as such, D is much pickier about implicit conversions in general. Occasionally, the restrictions are annoying, but they also prevent bugs. I have no idea whether Walter could be convinced at this point to allow some sort of implicit construction in D or not. Personally, I tend to think that we'd be better off if we didn't have alias this at all, because it tends to cause problems in anything outside of simple use cases (especially with generic code - implicit conversions in generic code are almost always a terrible idea). Sometimes, it's useful, but it's often just a recipe for subtle bugs. But at least the fact that D only allows you to implicitly convert in one direction reduces the problem. - Jonathan M Davis
Mar 24 2018
On 25/03/18 04:51, Jonathan M Davis wrote:On Sunday, March 25, 2018 00:47:20 Dave Jones via Digitalmars-d wrote:That's a good reason to disallow assignment from int to Foo. I see zero sense in allowing assignment and disallowing construction. ***** Technically, I understand the mechanisms at play here. During construction, this is a Foo object, and it has no construction from int. During assignment, we are allowed to convert a Foo lvalue to a Foo.x (int) lvalue, and that gets assigned. Despite understanding the mechanics, I find the end result surprising and unexpected. D makes it damn easy to implicitly expose an inner member, and much more difficult to actually do this safely (you have to create a property and then alias this that property). If I'd be building C++ today, I'd replace the "explicit" keyword with "implicit" (i.e. - still allow single var constructors to become implicit conversion ops, but make that transformation an opt-in rather than an opt-out feature). I think that would have been a much better approach than what D took. Shacharstruct Foo { int x; alias x this; } Foo f = 12; // error Foo foo; f = 12; // this is OK any reason why the first cant be allowed?Because it was deemed to cause too many problems. C++ code can have quite a few problems related to all of the implicit conversions it allows with stuff like constructing objects. Walter decided that D would be better off if it did not allow such conversions, and as such, D is much pickier about implicit conversions in general.
Mar 24 2018
On Sunday, March 25, 2018 06:24:35 Shachar Shemesh via Digitalmars-d wrote:On 25/03/18 04:51, Jonathan M Davis wrote:Having something like opImplicitCast would arguably have been better than alias this.On Sunday, March 25, 2018 00:47:20 Dave Jones via Digitalmars-d wrote:That's a good reason to disallow assignment from int to Foo. I see zero sense in allowing assignment and disallowing construction. ***** Technically, I understand the mechanisms at play here. During construction, this is a Foo object, and it has no construction from int. During assignment, we are allowed to convert a Foo lvalue to a Foo.x (int) lvalue, and that gets assigned. Despite understanding the mechanics, I find the end result surprising and unexpected. D makes it damn easy to implicitly expose an inner member, and much more difficult to actually do this safely (you have to create a property and then alias this that property).struct Foo { int x; alias x this; } Foo f = 12; // error Foo foo; f = 12; // this is OK any reason why the first cant be allowed?Because it was deemed to cause too many problems. C++ code can have quite a few problems related to all of the implicit conversions it allows with stuff like constructing objects. Walter decided that D would be better off if it did not allow such conversions, and as such, D is much pickier about implicit conversions in general.If I'd be building C++ today, I'd replace the "explicit" keyword with "implicit" (i.e. - still allow single var constructors to become implicit conversion ops, but make that transformation an opt-in rather than an opt-out feature). I think that would have been a much better approach than what D took.That would be a significant improvement for C++, though over time, I've increasingly become of the opinion that adding implicit conversions to user-defined types is more trouble than it's worth. There are certainly times when it's useful, but it causes enough problems that I'm not at all convinced that it's ultimately a feature worth having. And with the route that D went, implicit conversions are arguably crippled anyway. So, we have a partial solution that isn't really enough to cleanly use implicit conversions when it might be appropriate, but what we have is still enough to cause problems. - Jonathan M Davis
Mar 24 2018
On Sunday, 25 March 2018 at 00:47:20 UTC, Dave Jones wrote:struct Foo { int x; alias x this; } Foo f = 12; // errorYou just need to define a constructor that takes an int. alias this is all about taking an existing object and substituting a member for it - emphasis on *existing* object, so it needs to already be constructed. But you can construct from other types struct Foo { int x; this(int x) { this.x = x; } } Foo f = 12; // allowed, calls that constructorFoo foo; f = 12; // this is OKImportant to note that foo already exists here and is NOT reconstructed - the compiler just rewrites that into `f.x = 12;`, doing a member assignment.
Mar 24 2018