digitalmars.D.learn - Template mixins and struct constructors
- Adrian Matoga (34/34) Mar 02 2016 I can do this:
- Daniel Kozak (19/53) Mar 02 2016 You can use string mixins:
- Adrian Matoga (3/23) Mar 02 2016 What if T is private type in some other module or, even worse, a
- Daniel Kozak (21/49) Mar 02 2016 OK maybe this one:
- Adrian Matoga (10/30) Mar 02 2016 Then it's limited to structs in which only "int a" is to be
- Daniel Kozak (25/58) Mar 02 2016 OK then:
- Daniel Kozak (13/47) Mar 02 2016 I would say it is by design. What this will generate is something
- Adam D. Ruppe (6/8) Mar 02 2016 That's by design. It allows you to override names from a template
- Daniel Kozak via Digitalmars-d-learn (3/11) Mar 02 2016 I know it :). I need to upgrade my memory. I spent all day looking for
- Adrian Matoga (8/16) Mar 03 2016 Ah, I was on vacation at that time so that's why I don't remember
I can do this: struct Foo { int a; string b; this(int a) { this.a = a; } this(Args...)(string b, auto ref Args args) { this.b = b; this(args); } } unittest { auto foo1 = Foo(5); auto foo2 = Foo("foo", 15); } However, the following code is invalid: mixin template AddField(T) { T b; this(Args...)(T b, auto ref Args args) { this.b = b; this(args); } } struct Bar { mixin AddField!string; int a; this(int a) { this.a = a; } } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); // line 31 } sctor.d(31): Error: constructor sctor.Bar.this (int a) is not callable using argument types (string, int) Is it by design or is it a bug? And, if it is by design, what is the reason for that?
Mar 02 2016
On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:I can do this: struct Foo { int a; string b; this(int a) { this.a = a; } this(Args...)(string b, auto ref Args args) { this.b = b; this(args); } } unittest { auto foo1 = Foo(5); auto foo2 = Foo("foo", 15); } However, the following code is invalid: mixin template AddField(T) { T b; this(Args...)(T b, auto ref Args args) { this.b = b; this(args); } } struct Bar { mixin AddField!string; int a; this(int a) { this.a = a; } } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); // line 31 } sctor.d(31): Error: constructor sctor.Bar.this (int a) is not callable using argument types (string, int) Is it by design or is it a bug? And, if it is by design, what is the reason for that?You can use string mixins: template AddField(T) { enum AddField = T.stringof ~ ` b; this(Args...)(` ~ T.stringof ~ ` b, auto ref Args args) { this.b = b; this(args); }`; } struct Bar { mixin(AddField!string); int a; this(int a) { this.a = a; } } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); // line 31 }
Mar 02 2016
On Wednesday, 2 March 2016 at 12:48:47 UTC, Daniel Kozak wrote:On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:What if T is private type in some other module or, even worse, a Voldemort type?(...)You can use string mixins: template AddField(T) { enum AddField = T.stringof ~ ` b; this(Args...)(` ~ T.stringof ~ ` b, auto ref Args args) { this.b = b; this(args); }`; } struct Bar { mixin(AddField!string); int a; this(int a) { this.a = a; } } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); // line 31 }
Mar 02 2016
On Wednesday, 2 March 2016 at 13:18:23 UTC, Adrian Matoga wrote:On Wednesday, 2 March 2016 at 12:48:47 UTC, Daniel Kozak wrote:OK maybe this one: template AddField(T) { T b; this(Args...)(T b, auto ref Args args) { this.b = b; this(args); } this(int a) { this.a = a; } } struct Bar { int a; mixin AddField!(string); } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); }On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:What if T is private type in some other module or, even worse, a Voldemort type?(...)You can use string mixins: template AddField(T) { enum AddField = T.stringof ~ ` b; this(Args...)(` ~ T.stringof ~ ` b, auto ref Args args) { this.b = b; this(args); }`; } struct Bar { mixin(AddField!string); int a; this(int a) { this.a = a; } } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); // line 31 }
Mar 02 2016
On Wednesday, 2 March 2016 at 14:36:59 UTC, Daniel Kozak wrote:OK maybe this one: template AddField(T) { T b; this(Args...)(T b, auto ref Args args) { this.b = b; this(args); } this(int a) { this.a = a; } } struct Bar { int a; mixin AddField!(string); } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); }Then it's limited to structs in which only "int a" is to be initialized. Not very useful and the templated ctor is not needed now. struct Baz { mixin AddField!string; // fail, no "int a" in Baz. ulong d; double x; string foo; }
Mar 02 2016
On Wednesday, 2 March 2016 at 14:50:15 UTC, Adrian Matoga wrote:On Wednesday, 2 March 2016 at 14:36:59 UTC, Daniel Kozak wrote:OK then: mixin template AddField(T) { T b; auto ref constructor(Args...)(T b, auto ref Args args) { typeof(this) r; r.b = b; r.__ctor(args); return r; } } struct Bar { mixin AddField!string; int a; this(int a) { this.a = a; } alias __ctor = constructor; } unittest { import std.stdio; auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); writeln(bar1); writeln(bar2); }OK maybe this one: template AddField(T) { T b; this(Args...)(T b, auto ref Args args) { this.b = b; this(args); } this(int a) { this.a = a; } } struct Bar { int a; mixin AddField!(string); } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); }Then it's limited to structs in which only "int a" is to be initialized. Not very useful and the templated ctor is not needed now. struct Baz { mixin AddField!string; // fail, no "int a" in Baz. ulong d; double x; string foo; }
Mar 02 2016
On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:I can do this: struct Foo { int a; string b; this(int a) { this.a = a; } this(Args...)(string b, auto ref Args args) { this.b = b; this(args); } } unittest { auto foo1 = Foo(5); auto foo2 = Foo("foo", 15); } However, the following code is invalid: mixin template AddField(T) { T b; this(Args...)(T b, auto ref Args args) { this.b = b; this(args); } } struct Bar { mixin AddField!string; int a; this(int a) { this.a = a; } } unittest { auto bar1 = Bar(5); auto bar2 = Bar("bar", 15); // line 31 } sctor.d(31): Error: constructor sctor.Bar.this (int a) is not callable using argument types (string, int) Is it by design or is it a bug? And, if it is by design, what is the reason for that?I would say it is by design. What this will generate is something like: struct Bar { static struct _scope { string b; this(Args...)(string b, auto ref Args args) { this.b = b; this(args); } } int a; this(int a) { this.a = a; } }
Mar 02 2016
On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:Is it by design or is it a bug? And, if it is by design, what is the reason for that?That's by design. It allows you to override names from a template mixin like inheritance but no runtime cost. Read my tip of the week here to see how it works and how you can combine ctors from a mixin: http://arsdnet.net/this-week-in-d/2016-feb-07.html
Mar 02 2016
Dne 2.3.2016 v 21:39 Adam D. Ruppe via Digitalmars-d-learn napsal(a):On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:I know it :). I need to upgrade my memory. I spent all day looking for it in D cookbook, because I was sure it was you who make this tip somewhere.Is it by design or is it a bug? And, if it is by design, what is the reason for that?That's by design. It allows you to override names from a template mixin like inheritance but no runtime cost. Read my tip of the week here to see how it works and how you can combine ctors from a mixin: http://arsdnet.net/this-week-in-d/2016-feb-07.html
Mar 02 2016
On Wednesday, 2 March 2016 at 20:39:57 UTC, Adam D. Ruppe wrote:On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:Ah, I was on vacation at that time so that's why I don't remember reading it. :) Thanks! It's a nice workaround but it's, well, a workaround. It leaks the internals of the template mixin and a potential API user would have to remember two additional quirks when using it. I guess I'll try a different approach, initializing the mixed in members later with a function.Is it by design or is it a bug? And, if it is by design, what is the reason for that?That's by design. It allows you to override names from a template mixin like inheritance but no runtime cost. Read my tip of the week here to see how it works and how you can combine ctors from a mixin: http://arsdnet.net/this-week-in-d/2016-feb-07.html
Mar 03 2016