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.
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
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.