www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange casting error when using lamdas

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
I have very strange casting error I don't understand:

alias typeof(windows_message_streams[WM_MOUSEMOVE].filter!(win => 
(win.wParam & MK_LBUTTON))) WM_MOUSEMOVE_LBUTTON_TYPE;
WM_MOUSEMOVE_LBUTTON_TYPE WM_MOUSEMOVE_LBUTTON_STREAM;
pragma(msg,typeof(WM_MOUSEMOVE_LBUTTON_STREAM));

 FilterObservable!(__lambda39, SubjectObject!(OS_State))
WM_MOUSEMOVE_LBUTTON_STREAM = cast(WM_MOUSEMOVE_LBUTTON_TYPE)(windows_message_streams[WM_MO SEMOVE].filter!(win => (win.wParam & MK_LBUTTON))); pragma(msg,typeof(wstreams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))));
 FilterObservable!(__lambda7, SubjectObject!(OS_State))
..\..\gui.d(317,104): Error: cannot cast expression filter(windows_message_streams[512u]) of type FilterObservable!(__lambda6, SubjectObject!(OS_State)) to FilterObservable!(__lambda39, SubjectObject!(OS_State)) because of different sizes FilterObservable!(__lambda7, SubjectObject!(OS_State)) My code worked in the past but now it doesn't and I don't know why. I don't understand the "because of different sizes" message. It looks like I have to explicitly create a lambda and re-use it. But how to do that? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Dec 03 2019
next sibling parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-12-03 16:34:43 +0000, Robert M. Münch said:

 I have very strange casting error I don't understand:
 
 alias typeof(windows_message_streams[WM_MOUSEMOVE].filter!(win => 
 (win.wParam & MK_LBUTTON))) WM_MOUSEMOVE_LBUTTON_TYPE;
 WM_MOUSEMOVE_LBUTTON_TYPE WM_MOUSEMOVE_LBUTTON_STREAM;
 pragma(msg,typeof(WM_MOUSEMOVE_LBUTTON_STREAM));
 
 FilterObservable!(__lambda39, SubjectObject!(OS_State))
WM_MOUSEMOVE_LBUTTON_STREAM = cast(WM_MOUSEMOVE_LBUTTON_TYPE)(windows_message_streams[WM_MO SEMOVE].filter!(win => (win.wParam & MK_LBUTTON))); pragma(msg,typeof(wstreams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))));
 FilterObservable!(__lambda7, SubjectObject!(OS_State))
..\..\gui.d(317,104): Error: cannot cast expression filter(windows_message_streams[512u]) of type FilterObservable!(__lambda6, SubjectObject!(OS_State)) to FilterObservable!(__lambda39, SubjectObject!(OS_State)) because of different sizes FilterObservable!(__lambda7, SubjectObject!(OS_State)) My code worked in the past but now it doesn't and I don't know why. I don't understand the "because of different sizes" message. It looks like I have to explicitly create a lambda and re-use it. But how to do that?
The first three lines are on module level, the second two lines are inside a class member function. pragma(msg,WM_MOUSEMOVE_LBUTTON_STREAM.sizeof);
 8LU
but pragma(msg,windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON)).sizeof);
 16LU
Why do these two things have different sizes even the declaration is exactly the same? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Dec 03 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/3/19 12:35 PM, Robert M. Münch wrote:
 The first three lines are on module level, the second two lines are 
 inside a class member function.
 
 pragma(msg,WM_MOUSEMOVE_LBUTTON_STREAM.sizeof);
 
 8LU
but pragma(msg,windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON)).sizeof);
 16LU
Why do these two things have different sizes even the declaration is exactly the same?
Is one a delegate and one a function pointer? This can easily happen for untyped lambdas. -Steve
Dec 04 2019
next sibling parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-12-04 19:23:07 +0000, Steven Schveighoffer said:

 Is one a delegate and one a function pointer? This can easily happen 
 for untyped lambdas.
That's a very good point and hint. A function pointer will be 8LU and a delegate 16LU, right? This is a strong argument that this is really the problem. How can I find out? That's why I used a pragma to get the type of the alias. So, the alias needs to become a delegate. No clue how to write this down. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Dec 05 2019
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/5/19 3:57 AM, Robert M. Münch wrote:
 On 2019-12-04 19:23:07 +0000, Steven Schveighoffer said:
 
 Is one a delegate and one a function pointer? This can easily happen 
 for untyped lambdas.
That's a very good point and hint. A function pointer will be 8LU and a delegate 16LU, right? This is a strong argument that this is really the problem. How can I find out? That's why I used a pragma to get the type of the alias. So, the alias needs to become a delegate. No clue how to write this down.
Use std.functional.toDelegate. If it's already a delegate, it just returns the delegate, otherwise it makes a delegate out of a function pointer. -Steve
Dec 05 2019
prev sibling parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-12-04 19:23:07 +0000, Steven Schveighoffer said:

 Is one a delegate and one a function pointer? This can easily happen 
 for untyped lambdas.
Not sure if the code-snippets already give an explanation but the differences I have are: 1. Working case template filter(alias pred) { auto filter(TObservable)(auto ref TObservable observable) { static struct FilterObservable { ... } return FilterObservable(observable); } } 2. Non-Working case template filter(alias pred) { auto filter(TObservable)(auto ref TObservable observable) { return FilterObservable!(pred, TObservable)(observable); } } struct FilterObservable(alias pred, TObservable) { ... } The constructor has the same implementaion in both cases. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Dec 05 2019
prev sibling parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2019-12-03 16:34:43 +0000, Robert M. Münch said:

 I have very strange casting error I don't understand:
 
 alias typeof(windows_message_streams[WM_MOUSEMOVE].filter!(win => 
 (win.wParam & MK_LBUTTON))) WM_MOUSEMOVE_LBUTTON_TYPE;
 WM_MOUSEMOVE_LBUTTON_TYPE WM_MOUSEMOVE_LBUTTON_STREAM;
 pragma(msg,typeof(WM_MOUSEMOVE_LBUTTON_STREAM));
 
 FilterObservable!(__lambda39, SubjectObject!(OS_State))
WM_MOUSEMOVE_LBUTTON_STREAM = cast(WM_MOUSEMOVE_LBUTTON_TYPE)(windows_message_streams[WM_MO SEMOVE].filter!(win => (win.wParam & MK_LBUTTON))); pragma(msg,typeof(wstreams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))));
 FilterObservable!(__lambda7, SubjectObject!(OS_State))
..\..\gui.d(317,104): Error: cannot cast expression filter(windows_message_streams[512u]) of type FilterObservable!(__lambda6, SubjectObject!(OS_State)) to FilterObservable!(__lambda39, SubjectObject!(OS_State)) because of different sizes FilterObservable!(__lambda7, SubjectObject!(OS_State)) My code worked in the past but now it doesn't and I don't know why. I don't understand the "because of different sizes" message. It looks like I have to explicitly create a lambda and re-use it. But how to do that?
So, it all boils down to a breaking change in the RX framework... which I still don't understand... -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Dec 04 2019