digitalmars.D.learn - Some strange parameter deduction problems in opOpAssign and opBinary
- "Ivan Agafonov" <armadil yandex.ru> Sep 01 2012
- "Ivan Agafonov" <armadil yandex.ru> Sep 01 2012
- "Ivan Agafonov" <armadil yandex.ru> Sep 01 2012
- Philippe Sigaud <philippe.sigaud gmail.com> Sep 02 2012
- "Ivan Agafonov" <armadil yandex.ru> Sep 02 2012
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: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;
You don't need the alias.// 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
--20cf303b40a7587de004c8b33277 Content-Type: text/plain; charset=UTF-8Problem 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. --20cf303b40a7587de004c8b33277 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p><br> > Problem solved:<br> ><br> > alias Vec!(T, size) V;<br> ><br> > // This works fine<br> > ref V opOpAssign(string op)(V rhs)<br> ><br> > {<br> > =C2=A0 =C2=A0 =C2=A0 =C2=A0 mixin("array[] "~op~"=3D rh= s.array[];");<br> > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return this;<b= r> > }</p> <p>Inside a template, you can refer to the current (local) instantiation by= its name only. Try using 'Vec' instead of V. Does this work?</p> <p>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.= <br> </p> --20cf303b40a7587de004c8b33277--
Sep 02 2012
On Sunday, 2 September 2012 at 07:44:12 UTC, Philippe Sigaud wrote: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.
Yeah! Thanks. No need to alias. Needed simple Vec instead of Vec!(T, size)
Sep 02 2012









"Ivan Agafonov" <armadil yandex.ru> 