www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - mixed in struct constructor is ignored when another (non mixed in)

reply ParticlePeter <ParticlePeter gmx.de> writes:
mixin template Common() {
   private int m_member;
   this( int m ) { m_member = m; }
}

struct Foo {
   mixin Common;
}

struct Bar {
   mixin Common;
   this( int m, float n ) { m_member = m * n; }
}


auto foo = Foo(1);       // ok
auto b_1 = Bar( 1, 2 );  // ok
auto b_2 = Bar( 3 );     // Error: constructor main.Bar.this (int 
m, int n) is not callable using argument types (int)

Is this expected behavior?
Feb 26 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, February 26, 2018 12:30:24 ParticlePeter via Digitalmars-d-learn 
wrote:
 mixin template Common() {
    private int m_member;
    this( int m ) { m_member = m; }
 }

 struct Foo {
    mixin Common;
 }

 struct Bar {
    mixin Common;
    this( int m, float n ) { m_member = m * n; }
 }


 auto foo = Foo(1);       // ok
 auto b_1 = Bar( 1, 2 );  // ok
 auto b_2 = Bar( 3 );     // Error: constructor main.Bar.this (int
 m, int n) is not callable using argument types (int)

 Is this expected behavior?
Yes. Stuff that's mixed in is treated as having a different scope than other mixins or stuff that wasn't mixed in. To quote towards the bottom of here: https://dlang.org/spec/template-mixin.html "Alias declarations can be used to overload together functions declared in different mixins" It gives an example of mixin Foo!() F; mixin Bar!() B; alias func = F.func; alias func = B.func; I don't know if you can do the same thing with constructors or not, though alias this statements don't allow the = syntax. So, maybe that won't conflict, and it will work to do something like alias this = Common.this; If that doesn't work, then it seems like a good enhancement request. - Jonathan M Davis
Feb 26 2018
parent reply ParticlePeter <ParticlePeter gmx.de> writes:
On Monday, 26 February 2018 at 12:47:48 UTC, Jonathan M Davis 
wrote:
 On Monday, February 26, 2018 12:30:24 ParticlePeter via 
 Digitalmars-d-learn wrote:
 mixin template Common() {
    private int m_member;
    this( int m ) { m_member = m; }
 }

 struct Foo {
    mixin Common;
 }

 struct Bar {
    mixin Common;
    this( int m, float n ) { m_member = m * n; }
 }


 auto foo = Foo(1);       // ok
 auto b_1 = Bar( 1, 2 );  // ok
 auto b_2 = Bar( 3 );     // Error: constructor main.Bar.this 
 (int
 m, int n) is not callable using argument types (int)

 Is this expected behavior?
Yes. Stuff that's mixed in is treated as having a different scope than other mixins or stuff that wasn't mixed in. To quote towards the bottom of here: https://dlang.org/spec/template-mixin.html "Alias declarations can be used to overload together functions declared in different mixins" It gives an example of mixin Foo!() F; mixin Bar!() B; alias func = F.func; alias func = B.func; I don't know if you can do the same thing with constructors or not, though alias this statements don't allow the = syntax. So, maybe that won't conflict, and it will work to do something like alias this = Common.this; If that doesn't work, then it seems like a good enhancement request. - Jonathan M Davis
Thanks for clarification, unfortunately your suggestion doesn't work. Since when is alias this = something; supposed to work? alias Common.this this; doesn't work as well and following also not: struct Baz { Foo foo; alias foo this; this( int m, int n ) { m_member = m * n; } } auto baz = Baz(1); // Error, same as above Not sure if I do require an enhancement, I just stumbled on that and was wondering.
Feb 26 2018
parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Monday, 26 February 2018 at 13:09:40 UTC, ParticlePeter wrote:
 Thanks for clarification, unfortunately your suggestion doesn't 
 work.
 Since when is alias this = something; supposed to work?
 alias Common.this this; doesn't work as well and following also 
 not:

 struct Baz {
   Foo foo;
   alias foo this;
   this( int m, int n ) { m_member = m * n; }
 }

 auto baz = Baz(1); // Error, same as above

 Not sure if I do require an enhancement, I just stumbled on 
 that and was wondering.
The workaround for now is to define your other constructor in another mixin template: struct Bar { mixin Common; mixin template Common2() {this( int m, float n ) { m_member = cast(int)(m * n); } }; mixin Common2; } It's not exactly pretty, but it works. An issue has already been filed for this: https://issues.dlang.org/show_bug.cgi?id=17055. -- Simen
Feb 26 2018
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 26 February 2018 at 12:30:24 UTC, ParticlePeter wrote:
 Is this expected behavior?
yes sort of, but there are bugs associated with it too... I wrote about this in the "Tip of the Week" section here before http://arsdnet.net/this-week-in-d/2016-feb-07.html there's a workaround there and a bit more explanation of weirdness.
Feb 26 2018
parent reply ParticlePeter <ParticlePeter gmx.de> writes:
On Monday, 26 February 2018 at 14:02:56 UTC, Adam D. Ruppe wrote:
 On Monday, 26 February 2018 at 12:30:24 UTC, ParticlePeter 
 wrote:
 Is this expected behavior?
yes sort of, but there are bugs associated with it too... I wrote about this in the "Tip of the Week" section here before http://arsdnet.net/this-week-in-d/2016-feb-07.html there's a workaround there and a bit more explanation of weirdness.
This cool, I didn't know that we can name mixins when instantiating but also never taught that there could be any purpose for naming. Works, thanks.
Feb 26 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 26 February 2018 at 14:38:22 UTC, ParticlePeter wrote:
 This cool, I didn't know that we can name mixins when 
 instantiating but also never taught that there could be any 
 purpose for naming. Works, thanks.
oh yes, there's a lot of cool things with mixin. You might want to skim my tip of the week index: http://arsdnet.net/this-week-in-d/totw-index.html and see if more jump out at you. template mixins have behavior that look stupid until you understand why - then it gets pretty nice. Like the naming and overloading rules allow selective overriding and integration once you know how.
Feb 26 2018
parent ParticlePeter <ParticlePeter gmx.de> writes:
On Monday, 26 February 2018 at 14:42:58 UTC, Adam D. Ruppe wrote:
 On Monday, 26 February 2018 at 14:38:22 UTC, ParticlePeter 
 wrote:
 This cool, I didn't know that we can name mixins when 
 instantiating but also never taught that there could be any 
 purpose for naming. Works, thanks.
oh yes, there's a lot of cool things with mixin. You might want to skim my tip of the week index: http://arsdnet.net/this-week-in-d/totw-index.html and see if more jump out at you. template mixins have behavior that look stupid until you understand why - then it gets pretty nice. Like the naming and overloading rules allow selective overriding and integration once you know how.
Ok and that is an awesome link as well, I wished having this on several occasions. By the way, I also remembered reading your tip already once ... yeah, while reading it again. Anyway, thanks.
Feb 26 2018