digitalmars.D.learn - Problem with templated alias as delegate parameter type
- cc (58/58) Jan 12 2021 Given the following program:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (6/8) Jan 12 2021 That wants a delegate that takes a T.RESPONSE (PingResponse in this
- cc (6/14) Jan 12 2021 That seems to work, thanks. I ended up having to define a second
Given the following program: struct PingQuery { string msg; } struct PingResponse { string msg; } template send(T) { void send(T query, void delegate(PingResponse) callback) { writefln("Sending: %s", query); if (callback) { PingResponse resp; resp.msg = query.msg; callback(resp); } } } void main() { send(PingQuery("helo"), (resp) { writefln("Got response: %s", resp); }); } This works, but as you can see the PingResponse struct is hardcoded in the send function. If I try to make it a part of the template in a way such as this: struct PingQuery { alias RESPONSE = PingResponse; string msg; } struct PingResponse { string msg; } template send(T) { static assert(is(T.RESPONSE == PingQuery.RESPONSE)); // this succeeds at least void send(T query, void delegate(T.RESPONSE) callback) { writefln("Sending: %s", query); if (callback) { T.RESPONSE resp; resp.msg = query.msg; callback(resp); } } } void main() { send(PingQuery("helo"), (resp) { writefln("Got response: %s", resp); }); } I get: delegatetest.d(48): Error: template `delegatetest.send` cannot deduce function from argument types `!()(PingQuery, void)`, candidates are: delegatetest.d(35): `send(T)(T query, void delegate(T.RESPONSE) callback)` Same error if I use a nested struct (e.g. struct PingQuery { struct RESPONSE {} }) instead of an alias. Currently using DMD32 D Compiler v2.095.0-dirty (win64).
Jan 12 2021
On 1/12/21 12:58 PM, cc wrote:void send(T query, void delegate(T.RESPONSE) callback) {That wants a delegate that takes a T.RESPONSE (PingResponse in this case). However, the following lambda is in fact a template:send(PingQuery("helo"), (resp) {You specify the type there and it works: send(PingQuery("helo"), (PingResponse resp) { Ali
Jan 12 2021
On Tuesday, 12 January 2021 at 21:32:14 UTC, Ali Çehreli wrote:On 1/12/21 12:58 PM, cc wrote:That seems to work, thanks. I ended up having to define a second template parameter: template send(T,TR) if (is(TR == T.RESPONSE)) { void send(T query, void delegate(TR) callback) { ...void send(T query, void delegate(T.RESPONSE) callback) {That wants a delegate that takes a T.RESPONSE (PingResponse in this case). However, the following lambda is in fact a template:send(PingQuery("helo"), (resp) {You specify the type there and it works: send(PingQuery("helo"), (PingResponse resp) { Ali
Jan 12 2021