www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problem with templated alias as delegate parameter type

reply cc <cc nevernet.com> writes:
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
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
parent cc <cc nevernet.com> writes:
On Tuesday, 12 January 2021 at 21:32:14 UTC, Ali Çehreli wrote:
 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
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) { ...
Jan 12 2021