digitalmars.D.learn - Member function passed through template alias only requiring `this` in
- Emma (33/33) Jul 19 2018 Hello,
- =?UTF-8?Q?Ali_=c3=87ehreli?= (13/42) Jul 19 2018 I think it's a compiler bug. The second template argument should be a
- Timoses (38/63) Jul 19 2018 That is for the version of calling test with one lamdba and one
Hello, I’ve got this piece of code: --- import std.stdio; void test(alias fn1, alias fn2)() { fn1(); fn2(); } struct Foo { void foo() { test!(bar, baz); } void bar() {} void baz() {} } --- If I try to compile it, dmd complains, which I guess makes sense: --- Error: need this for bar of type void() Error: need this for baz of type void() --- However, if I change line 13 from `test!(bar, baz);` to `test!(() => bar, baz);`, it compiles and executes fine, calling both the `bar` and `baz` member functions. Why is this? Shouldn’t it complain about `baz` needing `this`? Does the lambda in the first template argument somehow “pull in” the `this` reference for `baz`, too? Thanks!
Jul 19 2018
On 07/19/2018 08:12 AM, Emma wrote:void test(alias fn1, alias fn2)() { fn1(); fn2(); } struct Foo { void foo() { test!(bar, baz); } void bar() {} void baz() {} } --- If I try to compile it, dmd complains, which I guess makes sense: --- Error: need this for bar of type void() Error: need this for baz of type void() --- However, if I change line 13 from `test!(bar, baz);` to `test!(() => bar, baz);`, it compiles and executes fine, calling both the `bar` and `baz` member functions. Why is this? Shouldn’t it complain about `baz` needing `this`? Does the lambda in the first template argument somehow “pull in” the `this` reference for `baz`, too? Thanks!I think it's a compiler bug. The second template argument should be a lambda as well. When I added the following lines to test() pragma(msg, typeof(fn1)); pragma(msg, typeof(fn2)); the output is different: void delegate() system void() I think it's a bug probably related to multiple local lambdas. We had similar issues in the past. Although it works as is, I recommend you make the second one a lambda as well. Others, please confirm that it's a bug and let's create a bug report. Ali
Jul 19 2018
On Thursday, 19 July 2018 at 22:16:22 UTC, Ali Çehreli wrote:On 07/19/2018 08:12 AM, Emma wrote:That is for the version of calling test with one lamdba and one function? (`test!(() => bar, baz)`) Just a question: The compiler should not automatically convert those (functions) to lambdas? Interesting is this: void test(alias fn1, alias fn2)() { pragma(msg, typeof(fn1)); // void delegate() system pragma(msg, typeof(fn2)); // void() fn1(); fn2(); // Error: this for baz needs to be type Boo not type Foo } struct Foo { void foo() { test!(()=>bar, b.baz); } int i = 1337; struct Boo { int j = 3; void baz() {writeln(j);} } Boo b; void bar() {writeln(i);} } unittest { auto foo = Foo(); foo.foo(); } Looks like the compiler just assumes the context of the first delegate to be applicable for the second function?[...] If I try to compile it, dmd complains, which I guess makessense:--- Error: need this for bar of type void() Error: need this for baz of type void() --- [...]I think it's a compiler bug. The second template argument should be a lambda as well. When I added the following lines to test() pragma(msg, typeof(fn1)); pragma(msg, typeof(fn2)); the output is different: void delegate() system void()I think it's a bug probably related to multiple local lambdas. We had similar issues in the past. Although it works as is, I recommend you make the second one a lambda as well. Others, please confirm that it's a bug and let's create a bug report. Ali
Jul 19 2018