Re: Member function passed through template alias only requiring `this` in certain conditions?

2018-07-19 Thread Timoses via Digitalmars-d-learn

On Thursday, 19 July 2018 at 22:16:22 UTC, Ali Çehreli wrote:

On 07/19/2018 08:12 AM, Emma wrote:
> [...]
> 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()
> ---
>
> [...]

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()


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?




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





Re: Member function passed through template alias only requiring `this` in certain conditions?

2018-07-19 Thread Ali Çehreli via Digitalmars-d-learn

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



Member function passed through template alias only requiring `this` in certain conditions?

2018-07-19 Thread Emma via Digitalmars-d-learn

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!