digitalmars.D.learn - Placement of shared does not allow to set a delegate
- Tolga Cakiroglu (26/26) Jun 16 2014 In a class I defined an event attribute as follows:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (28/50) Jun 16 2014 shared{}
- Tolga Cakiroglu (8/34) Jun 16 2014 Thanks Ali. That has solved the problem. Actually I tried to use
- Tolga Cakiroglu (27/53) Jun 16 2014 Okay, now I continue with another thing. After defining the event
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (38/64) Jun 16 2014 The second type is different with dmd 2.066:
- Tolga Cakiroglu (36/50) Jun 19 2014 Yes the understanding is correct. I simplified the code a little:
In a class I defined an event attribute as follows: public void delegate( shared(SocketListener) sender ) eventWhenStarted; --- An instance of SocketListener is created. auto listener = new shared SocketListener(); --- I defined a shared method that will be called when the event occurs. public void listener_whenStarted( shared(SocketListener) sender ) shared{} --- I set the event attribute of listener to defined method: listener.eventWhenStarted = &listener_whenStarted; ---- Here is the error message: main.d(21): Error: cannot implicitly convert expression (&this.listener_whenStarted) of type void delegate(shared(SocketListener) sender) shared to shared(void delegate(shared(SocketListener))) If we look at types separately as follows: .......void delegate(shared(SocketListener) sender) shared shared(void delegate(shared(SocketListener))) Isn't the first type same as the second one? (1.5 years later, I still hate the `shared` keyword. It is nothing but confusion and extra coding for many programmers.)
Jun 16 2014
On 06/16/2014 05:35 AM, Tolga Cakiroglu wrote:> In a class I defined an event attribute as follows:public void delegate( shared(SocketListener) sender ) eventWhenStarted; --- An instance of SocketListener is created. auto listener = new shared SocketListener(); --- I defined a shared method that will be called when the event occurs. public void listener_whenStarted( shared(SocketListener) sender )shared{}--- I set the event attribute of listener to defined method: listener.eventWhenStarted = &listener_whenStarted; ---- Here is the error message: main.d(21): Error: cannot implicitly convert expression (&this.listener_whenStarted) of type void delegate(shared(SocketListener) sender) shared to shared(void delegate(shared(SocketListener))) If we look at types separately as follows: .......void delegate(shared(SocketListener) sender) shared shared(void delegate(shared(SocketListener))) Isn't the first type same as the second one? (1.5 years later, I still hate the `shared` keyword. It is nothing but confusion and extra coding for many programmers.)Here is a minimal example that reproduces the issue and the hint that compiles the code: class SocketListener { public void delegate( shared(SocketListener) sender ) /* shared */ // <-- UNCOMMENT TO COMPILE eventWhenStarted; } class C { this() { auto listener = new shared SocketListener(); listener.eventWhenStarted = &listener_whenStarted; } public void listener_whenStarted( shared(SocketListener) sender ) shared {} } void main() {} Error: cannot implicitly convert expression (&this.listener_whenStarted) of type void delegate(shared(SocketListener) sender) shared to shared(void delegate(shared(SocketListener))) Ali
Jun 16 2014
Thanks Ali. That has solved the problem. Actually I tried to use that `shared` as follows before: public shared void delegate( shared(BasicSocketListener) sender ) eventWhenStarted; Though it didn't work with that. When it is put "before" the attribute name, it works now. It is just confusing where to put it to. On Monday, 16 June 2014 at 15:25:51 UTC, Ali Çehreli wrote:Here is a minimal example that reproduces the issue and the hint that compiles the code: class SocketListener { public void delegate( shared(SocketListener) sender ) /* shared */ // <-- UNCOMMENT TO COMPILE eventWhenStarted; } class C { this() { auto listener = new shared SocketListener(); listener.eventWhenStarted = &listener_whenStarted; } public void listener_whenStarted( shared(SocketListener) sender ) shared {} } void main() {} Error: cannot implicitly convert expression (&this.listener_whenStarted) of type void delegate(shared(SocketListener) sender) shared to shared(void delegate(shared(SocketListener))) Ali
Jun 16 2014
On Monday, 16 June 2014 at 15:25:51 UTC, Ali Çehreli wrote:Here is a minimal example that reproduces the issue and the hint that compiles the code: class SocketListener { public void delegate( shared(SocketListener) sender ) /* shared */ // <-- UNCOMMENT TO COMPILE eventWhenStarted; } class C { this() { auto listener = new shared SocketListener(); listener.eventWhenStarted = &listener_whenStarted; } public void listener_whenStarted( shared(SocketListener) sender ) shared {} } void main() {} Error: cannot implicitly convert expression (&this.listener_whenStarted) of type void delegate(shared(SocketListener) sender) shared to shared(void delegate(shared(SocketListener))) AliOkay, now I continue with another thing. After defining the event attribute as follows public void delegate( shared(SocketListener) sender ) shared eventWhenStarted; --- I removed the "shared" keyword from that method public void listener_whenStarted( shared(SocketListener) sender ){} --- Then set the attribute as follows listener.eventWhenStarted = cast(shared)(&listener_whenStarted); --- There is error again. main.d(21): Error: cannot implicitly convert expression (&this.listener_whenStarted) of type shared(void delegate(shared(SocketListener))) to shared(void delegate(shared(SocketListener))) --- This error is important, because both types are completely same: main.d(21): Error: cannot implicitly convert expression (&this.listener_whenStarted) of type shared(void delegate(shared(SocketListener))) to shared(void delegate(shared(SocketListener))) --- Can this be a bug?
Jun 16 2014
On 06/16/2014 09:37 AM, Tolga Cakiroglu wrote:On Monday, 16 June 2014 at 15:25:51 UTC, Ali Çehreli wrote:Okay, now I continue with another thing. After defining the event attribute as follows public void delegate( shared(SocketListener) sender ) shared eventWhenStarted; --- I removed the "shared" keyword from that method public void listener_whenStarted( shared(SocketListener) sender ){} --- Then set the attribute as follows listener.eventWhenStarted = cast(shared)(&listener_whenStarted); --- There is error again. main.d(21): Error: cannot implicitly convert expression (&this.listener_whenStarted) of type shared(void delegate(shared(SocketListener))) to shared(void delegate(shared(SocketListener))) --- This error is important, because both types are completely same: main.d(21): Error: cannot implicitly convert expression (&this.listener_whenStarted) of type shared(void delegate(shared(SocketListener))) to shared(void delegate(shared(SocketListener)))The second type is different with dmd 2.066: Error: cannot implicitly convert expression (&this.listener_whenStarted) of type shared(void delegate(shared(SocketListener))) to shared(void delegate(shared(SocketListener)) shared) However, I may have misunderstood your description. This is the code I tried: class SocketListener { public void delegate( shared(SocketListener) sender ) shared eventWhenStarted; } class C { this() { auto listener = new shared SocketListener(); listener.eventWhenStarted = cast(shared)&listener_whenStarted; } public void listener_whenStarted( shared(SocketListener) sender ) {} } void main() {}--- Can this be a bug?I don't know but I theorize like this: :) There are three 'shared' qualifiers in the last error message. shared(void delegate(shared(SocketListener)) shared) 1) The 'shared' in the middle: That one makes the delegate take a shared(SocketListener) argument when it gets called. 2) The 'shared' on the right-hand side: (I am not sure about this one.) That one makes the context pointer of the delegate 'shared'. For example, the delegate can only be called on a shared class object. 3) The 'shared' on the left-hand side: That one makes the type of the delegate shared so that e.g. such a delegate can be passed between threads. That's what I understand. Ali
Jun 16 2014
Yes the understanding is correct. I simplified the code a little: IMPORTANT: DMD 2.065 is used. class Car{ void delegate() onEvent; } class Test{ this() shared { auto car = new shared Car(); assert( typeid( car.onEvent ).toString() == "shared(void delegate())" ); assert( typeid( &car_onEvent1 ).toString() == "void delegate()" ); assert( typeid( &car_onEvent2 ).toString() == "void delegate()" ); assert( typeid( cast(shared)( &car_onEvent2 ) ).toString() == "shared(void delegate())" ); car.onEvent = &car_onEvent1; car.onEvent = &car_onEvent2; // COMPILATION ERROR car.onEvent = cast(shared)( &car_onEvent2 ); // COMPILATION ERROR } void car_onEvent1(){} void car_onEvent2() shared{} } void main(){ new shared Test(); } I just want to know if I am doing a mistake, thinking in wrong way, or there is a bug. The first compilation error is that it cannot convert "void delegate() shared" to "shared(void delegate())". The second compilation error is that it cannot convert "shared(void delegate())" to "shared(void delegate())". (Since DMD 2.066 is not ready yet, I need to continue with 2.065.) On Tuesday, 17 June 2014 at 04:35:10 UTC, Ali Çehreli wrote:I don't know but I theorize like this: :) There are three 'shared' qualifiers in the last error message. shared(void delegate(shared(SocketListener)) shared) 1) The 'shared' in the middle: That one makes the delegate take a shared(SocketListener) argument when it gets called. 2) The 'shared' on the right-hand side: (I am not sure about this one.) That one makes the context pointer of the delegate 'shared'. For example, the delegate can only be called on a shared class object. 3) The 'shared' on the left-hand side: That one makes the type of the delegate shared so that e.g. such a delegate can be passed between threads. That's what I understand. Ali
Jun 19 2014