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








 
  
  
 
 Daniel Kozak <kozzi11 gmail.com>
 Daniel Kozak <kozzi11 gmail.com> 