www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - operator overloading compilation error

reply =?ISO-8859-1?Q?Diego_Canuh=E9?= <canuhedc gmail.com> writes:
--bcaec51a7d4068a7ed04a8f6dbcd
Content-Type: text/plain; charset=ISO-8859-1

Hi
I'm trying to overload the "+" and "-" operators for a struct  but I get
this error

test.d(47): Error: incompatible types for ((v1) - (v2)): 'Vecf!(1u)' and
'Vecf!(1u)'
(the line corresponds to the last assert)

doing something like this

struct Vecf(uint n)
{
    ...
    Vecf!n opBinary(string op)(Vecf!n other) if (op == "+" || op == "-")
{...}
}

void main()
{
    Vecf!1u v1 = Vecf!1u(3f);
    Vecf!1u v2 = Vecf!1u(5f);
    Vecf!1u r = Vecf!1u(-2f);
    assert ((v1.opBinary!"-"(v2)) == r);
    assert ((v1 - v2) == r);
}

removing the last assert or replacing (Vecf!n other) by (Vecf!1u other) in
the function declaration works fine, but it's not what I want

Any ideas? maybe I'm overloading the operators in the wrong way (it worked
in a very similar test though)?

Thanks!!

Here's the full code:

-------------------------------------------------------------------
module test;

import std.stdio;

struct Vecf(uint n)
{
    float[n] data;


    this(float[n] args ...)
    {
        foreach (i, a; args)
        {
            data[i] = a;
        }
    }

    float opIndex(uint i)
    {
        return data[i];
    }

    float opIndexAssign(float value, uint i)
    {
        data[i] = value;
        return value;
    }

    Vecf!n opBinary(string op)(Vecf!n other) if (op == "+" || op == "-")
    {
        Vecf!n ret;

        for (size_t i = 0; i < n; i++)
        {
            mixin("ret[i] = this[i] " ~ op ~ " other[i];");
        }
        return ret;
    }
}

void main()
{
    Vecf!1u v1 = Vecf!1u(3f);
    Vecf!1u v2 = Vecf!1u(5f);
    Vecf!1u r = Vecf!1u(-2f);
    assert ((v1.opBinary!"-"(v2)) == r);
    assert ((v1 - v2) == r);
}
--------------------------------------------------------------------------------------

--bcaec51a7d4068a7ed04a8f6dbcd
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi<br>I&#39;m trying to overload the &quot;+&quot; and &quot;-&quot; operat=
ors for a struct=A0 but I get this error<br><br>test.d(47): Error: incompat=
ible types for ((v1) - (v2)): &#39;Vecf!(1u)&#39; and &#39;Vecf!(1u)&#39;<b=
r>
(the line corresponds to the last assert)<br><br>doing something like this<=
br><br>struct Vecf(uint n)<br>
{<br>=A0=A0=A0 ...<br>=A0=A0=A0 Vecf!n opBinary(string op)(Vecf!n other) if=
 (op =3D=3D &quot;+&quot; || op =3D=3D &quot;-&quot;) {...}<br>}<br><br>voi=
d main()<br>{<br>=A0=A0=A0 Vecf!1u v1 =3D Vecf!1u(3f);<br>
=A0=A0=A0 Vecf!1u v2 =3D Vecf!1u(5f);<br>
=A0=A0=A0 Vecf!1u r =3D Vecf!1u(-2f);<br>
=A0=A0=A0 assert ((v1.opBinary!&quot;-&quot;(v2)) =3D=3D r);<br>
=A0=A0=A0 assert ((v1 - v2) =3D=3D r);<br>}<br><br>removing the last assert=
 or replacing (Vecf!n other) by (Vecf!1u other) in the function declaration=
 works fine, but it&#39;s not what I want<br><br>Any ideas? maybe I&#39;m o=
verloading the operators in the wrong way (it worked in a very similar test=
 though)?<br>
<br>Thanks!!<br><br>Here&#39;s the full code:<br><br>----------------------=
---------------------------------------------<br>module test;<br><br>import=
 std.stdio;<br><br>struct Vecf(uint n)<br>{<br>=A0=A0=A0 float[n] data;<br>=
=A0=A0=A0 <br>
=A0=A0=A0 <br>=A0=A0=A0 this(float[n] args ...)<br>=A0=A0=A0 {<br>=A0=A0=A0=
=A0=A0=A0=A0 foreach (i, a; args)<br>=A0=A0=A0=A0=A0=A0=A0 {<br>=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 data[i] =3D a;<br>=A0=A0=A0=A0=A0=A0=A0 }<br>=A0=
=A0=A0 }<br>=A0=A0=A0 <br>=A0=A0=A0 float opIndex(uint i)<br>=A0=A0=A0 {<br=
=A0=A0=A0=A0=A0=A0=A0 return data[i];<br>=A0=A0=A0 }<br>

=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 data[i] =3D value;<br>=A0=A0=A0=A0=A0=A0=A0 = return value;<br>=A0=A0=A0 }<br>=A0=A0=A0 <br>=A0=A0=A0 Vecf!n opBinary(str= ing op)(Vecf!n other) if (op =3D=3D &quot;+&quot; || op =3D=3D &quot;-&quot= ;)<br> =A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0 Vecf!n ret;<br>=A0=A0=A0=A0=A0=A0=A0 <= br>=A0=A0=A0=A0=A0=A0=A0 for (size_t i =3D 0; i &lt; n; i++)<br>=A0=A0=A0= =A0=A0=A0=A0 {<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 mixin(&quot;ret[i] =3D = this[i] &quot; ~ op ~ &quot; other[i];&quot;);<br>=A0=A0=A0=A0=A0=A0=A0 }<b= r>=A0=A0=A0=A0=A0=A0=A0 return ret;<br> =A0=A0=A0 }<br>}<br><br>void main()<br>{<br>=A0=A0=A0 Vecf!1u v1 =3D Vecf!1= u(3f);<br>=A0=A0=A0 Vecf!1u v2 =3D Vecf!1u(5f);<br>=A0=A0=A0 Vecf!1u r =3D = Vecf!1u(-2f);<br>=A0=A0=A0 assert ((v1.opBinary!&quot;-&quot;(v2)) =3D=3D r= );<br>=A0=A0=A0 assert ((v1 - v2) =3D=3D r);<br> }<br>----------------------------------------------------------------------= ----------------<br><br><br> --bcaec51a7d4068a7ed04a8f6dbcd--
Jul 26 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Diego Canuhé:

 I'm trying to overload the "+" and "-" operators for a struct  but I get
 this error
 
 test.d(47): Error: incompatible types for ((v1) - (v2)): 'Vecf!(1u)' and
 'Vecf!(1u)'
 (the line corresponds to the last assert)

It's a dmd bug, and I think it's already in Bugzilla. This is workaround code: struct Vecf(uint n) { float x; Vecf opBinary(string op)(Vecf other) if (op == "+" || op == "-") { mixin("return Vecf(this.x " ~ op ~ " other.x);"); } } void main() { alias Vecf!1 V; auto v1 = V(3f); auto v2 = V(5f); auto r = V(-2f); assert ((v1.opBinary!"-"(v2)) == r); // better to use an approximate == assert ((v1 - v2) == r); // better to use an approximate == } Bye, bearophile
Jul 26 2011
prev sibling parent =?ISO-8859-1?Q?Diego_Canuh=E9?= <canuhedc gmail.com> writes:
--20cf3071d06af6142204a8f84220
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

thanks!

On Tue, Jul 26, 2011 at 9:12 AM, bearophile <bearophileHUGS lycos.com>wrote=
:

 Diego Canuh=E9:

 I'm trying to overload the "+" and "-" operators for a struct  but I ge=


 this error

 test.d(47): Error: incompatible types for ((v1) - (v2)): 'Vecf!(1u)' an=


 'Vecf!(1u)'
 (the line corresponds to the last assert)

It's a dmd bug, and I think it's already in Bugzilla. This is workaround code: struct Vecf(uint n) { float x; Vecf opBinary(string op)(Vecf other) if (op =3D=3D "+" || op =3D=3D "-=

        mixin("return Vecf(this.x " ~ op ~ " other.x);");
    }
 }

 void main() {
    alias Vecf!1 V;
    auto v1 =3D V(3f);
    auto v2 =3D V(5f);
    auto r =3D V(-2f);
    assert ((v1.opBinary!"-"(v2)) =3D=3D r); // better to use an approxima=

    assert ((v1 - v2) =3D=3D r); // better to use an approximate =3D=3D
 }

 Bye,
 bearophile

--20cf3071d06af6142204a8f84220 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable thanks!<br><br><div class=3D"gmail_quote">On Tue, Jul 26, 2011 at 9:12 AM, = bearophile <span dir=3D"ltr">&lt;<a href=3D"mailto:bearophileHUGS lycos.com= ">bearophileHUGS lycos.com</a>&gt;</span> wrote:<br><blockquote class=3D"gm= ail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(2= 04, 204, 204); padding-left: 1ex;"> Diego Canuh=E9:<br> <div class=3D"im"><br> &gt; I&#39;m trying to overload the &quot;+&quot; and &quot;-&quot; operato= rs for a struct =A0but I get<br> &gt; this error<br> &gt;<br> &gt; test.d(47): Error: incompatible types for ((v1) - (v2)): &#39;Vecf!(1u= )&#39; and<br> &gt; &#39;Vecf!(1u)&#39;<br> &gt; (the line corresponds to the last assert)<br> <br> </div>It&#39;s a dmd bug, and I think it&#39;s already in Bugzilla. This is= workaround code:<br> <br> <br> struct Vecf(uint n) {<br> =A0 =A0float x;<br> =A0 =A0Vecf opBinary(string op)(Vecf other) if (op =3D=3D &quot;+&quot; ||= op =3D=3D &quot;-&quot;) {<br> =A0 =A0 =A0 =A0mixin(&quot;return Vecf(this.x &quot; ~ op ~ &quot; other.x= );&quot;);<br> =A0 =A0}<br> }<br> <br> void main() {<br> =A0 =A0alias Vecf!1 V;<br> =A0 =A0auto v1 =3D V(3f);<br> =A0 =A0auto v2 =3D V(5f);<br> =A0 =A0auto r =3D V(-2f);<br> =A0 =A0assert ((v1.opBinary!&quot;-&quot;(v2)) =3D=3D r); // better to use= an approximate =3D=3D<br> =A0 =A0assert ((v1 - v2) =3D=3D r); // better to use an approximate =3D=3D= <br> }<br> <br> Bye,<br> <font color=3D"#888888">bearophile<br> </font></blockquote></div><br> --20cf3071d06af6142204a8f84220--
Jul 26 2011