digitalmars.D.learn - Some strange parameter deduction problems in opOpAssign and opBinary
- Ivan Agafonov (38/38) Sep 01 2012 There are 3 separated versions of opOpAssign
- Ivan Agafonov (2/2) Sep 01 2012 Hmm, strange...
- Ivan Agafonov (10/49) Sep 01 2012 Problem solved:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/63) Sep 02 2012 The name of the template alone becomes the actual instantiation of that
- Philippe Sigaud (5/13) Sep 02 2012 Inside a template, you can refer to the current (local) instantiation by
- Ivan Agafonov (4/23) Sep 02 2012 Yeah! Thanks. No need to alias. Needed simple Vec instead of
There are 3 separated versions of opOpAssign first version must be the same as the second for Vec!(sometype, 4) why it doesn't work? Simplified code: struct Vec(T, uint size) { this(T rhs) { array[] = rhs; } // It doesn't work but compiles ref Vec!(T, size) opOpAssign(string op) (Vec!(T, size) rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } // but it work's ref Vec!(T, 4) opOpAssign(string op) (Vec!(T, 4) rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } // and this work;s ref Vec!(T, size) opAddAssign(Vec!(T, size) rhs) { array[] += rhs.array[]; return this; } T[size] array = 0; } int main() { auto z = Vec!(float, 4)(5.0f); z += z; writeln(z); return 0; }
Sep 01 2012
Hmm, strange... z.opOpAssign!"+"(z); works with both first and second versions
Sep 01 2012
On Sunday, 2 September 2012 at 04:10:39 UTC, Ivan Agafonov wrote:There are 3 separated versions of opOpAssign first version must be the same as the second for Vec!(sometype, 4) why it doesn't work? Simplified code: struct Vec(T, uint size) { this(T rhs) { array[] = rhs; } // It doesn't work but compiles ref Vec!(T, size) opOpAssign(string op) (Vec!(T, size) rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } // but it work's ref Vec!(T, 4) opOpAssign(string op) (Vec!(T, 4) rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } // and this work;s ref Vec!(T, size) opAddAssign(Vec!(T, size) rhs) { array[] += rhs.array[]; return this; } T[size] array = 0; } int main() { auto z = Vec!(float, 4)(5.0f); z += z; writeln(z); return 0; }Problem solved: alias Vec!(T, size) V; // This works fine ref V opOpAssign(string op)(V rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } But I think this is a bug.
Sep 01 2012
On 09/01/2012 10:08 PM, Ivan Agafonov wrote:On Sunday, 2 September 2012 at 04:10:39 UTC, Ivan Agafonov wrote:You don't need the alias.There are 3 separated versions of opOpAssign first version must be the same as the second for Vec!(sometype, 4) why it doesn't work? Simplified code: struct Vec(T, uint size) { this(T rhs) { array[] = rhs; } // It doesn't work but compiles ref Vec!(T, size) opOpAssign(string op) (Vec!(T, size) rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } // but it work's ref Vec!(T, 4) opOpAssign(string op) (Vec!(T, 4) rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; } // and this work;s ref Vec!(T, size) opAddAssign(Vec!(T, size) rhs) { array[] += rhs.array[]; return this; } T[size] array = 0; } int main() { auto z = Vec!(float, 4)(5.0f); z += z; writeln(z); return 0; }Problem solved: alias Vec!(T, size) V;// This works fine ref V opOpAssign(string op)(V rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; }The name of the template alone becomes the actual instantiation of that template. This should work: ref Vec opOpAssign(string op) (Vec rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; }But I think this is a bug.Which compiler? All three versions of your original code compiles and produces the same result with dmd 2.060 under 64-bit Linux. Ali
Sep 02 2012
Problem solved: alias Vec!(T, size) V; // This works fine ref V opOpAssign(string op)(V rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; }Inside a template, you can refer to the current (local) instantiation by its name only. Try using 'Vec' instead of V. Does this work? If you want to force the use of another instantiation, I personally put a dot ('.') before the template: this is the 'global scope' operator and the compiler will 'step out' of the current template.
Sep 02 2012
On Sunday, 2 September 2012 at 07:44:12 UTC, Philippe Sigaud wrote:Yeah! Thanks. No need to alias. Needed simple Vec instead of Vec!(T, size)Problem solved: alias Vec!(T, size) V; // This works fine ref V opOpAssign(string op)(V rhs) { mixin("array[] "~op~"= rhs.array[];"); return this; }Inside a template, you can refer to the current (local) instantiation by its name only. Try using 'Vec' instead of V. Does this work? If you want to force the use of another instantiation, I personally put a dot ('.') before the template: this is the 'global scope' operator and the compiler will 'step out' of the current template.
Sep 02 2012