D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 19710 - template parameters not deduced when one is is a supplied string, and the other inferred.
Summary: template parameters not deduced when one is is a supplied string, and the oth...
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P3 regression
Assignee: No Owner
URL: http://dlang.org/
Keywords:
Depends on:
Blocks:
 
Reported: 2019-02-28 23:51 UTC by Alex
Modified: 2019-03-04 00:54 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Alex 2019-02-28 23:51:28 UTC
import std.stdio;

void attribute(string attributeName,T)(ref T x)
{
	mixin(
		"x." ~ attributeName ~ " = 10;"
	);
}

void main()
{
	class A
	{
		int b;
		void load()
		{
			attribute!"b"(this);	//error: template main.attribute cannot deduce function from argument types !("b")(A), candidates are:    attribute!"b"(this);
		}
	}
	
	auto a = new A;
	attribute!"b"(a);	//OK.
	
	
}

This compiles in gdc 6, but fails in gdc8 and dlang.org web compiler.
Comment 1 Sprink 2019-03-02 23:04:10 UTC
Manually insert the type and you will see "this" is considered as an rvalue.

It was deprecated in DMD 2.067.1 to 2.071.2:

Deprecation: this is not an lvalue
Comment 2 Alex 2019-03-04 00:54:12 UTC
The solution I found was to make two versions of this attribute function with different names.
One for structs and one for classes.

The ref is necessary to have it work for structs.

The ref fails when used with 'this' in classes.

I think the underlying problem is that in the class version, the ref refers to the object reference (pointer), not the object pointed to, so the ref is unnecessary, and in the case where this is passed, illegal.

In the struct version, the ref refers to the object itself, and is necessary to prevent it being copied and operations happening to a local version.

This is a bit unfortunate, it would be nice to have a template that could work with either.