www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Two problems with op overload

reply bearophile <bearophileHUGS lycos.com> writes:
I have tried to use the new operators of D2 and I have found several problems.
This small program shows two of those problems (some of my problems can be
caused by my improper usage, I'm trying to tell apart the operator overloading
bugs from my improper usage cases).

Do you know if/how this program can be fixed?


struct Foo {
    int x;

    Foo opUnary(string op:"++")() {
        this.x++;
        return this;
    }

    uint opCast(T:uint)() {
        return this.x;
    }
}

void main() {
    Foo f = Foo(5);
    f++; // line 16
    auto a = new int[f]; // line 17
}

Errors:
temp2.d(16): Error: var has no effect in expression (__tmp1)
temp2.d(17): Error: cannot implicitly convert expression (f) of type Foo to uint

Note: the line 17 works if I write it this way, but it's not nice:
auto a = new int[cast(uint)f];

Bye,
bearophile
Mar 14 2010
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
--00032555a4e6da5fde0481c3a2ff
Content-Type: text/plain; charset=ISO-8859-1

On Sun, Mar 14, 2010 at 14:14, bearophile <bearophileHUGS lycos.com> wrote:

 I have tried to use the new operators of D2 and I have found several
 problems. This small program shows two of those problems (some of my
 problems can be caused by my improper usage, I'm trying to tell apart the
 operator overloading bugs from my improper usage cases).
 void main() {
    Foo f = Foo(5);
    f++; // line 16
    auto a = new int[f]; // line 17
 }

 Errors:
 temp2.d(16): Error: var has no effect in expression (__tmp1)

Try ++f, it works. I guess ++f is rewritten f.opUnary!"++"(), but f++ must have create a temporary variable.
 temp2.d(17): Error: cannot implicitly convert expression (f) of type Foo to
 uint

 Note: the line 17 works if I write it this way, but it's not nice:
 auto a = new int[cast(uint)f];

opCast defines the explicit cast operation, it has no effect on implicit casting. Having an opImplicitCast(T) would be nice, I agree. For now, this also does not work: void bar(int i) {} (in main:) bar(f); // Error: cannot implicitly convert expresion (f) of type Foo to int. That's sad, I'd like to have std.variant.Variant defining an opCast. That way, you could do: void foo(int i) {} void bar(string s) {} Variant v; v = 3; foo(v); // try to cast v to int implicitly: works, move along. v = "abc"; bar(v); // implicit cast to string, works. Philippe --00032555a4e6da5fde0481c3a2ff Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Sun, Mar 14, 2010 at 14:14, bearophil= e <span dir=3D"ltr">&lt;<a href=3D"mailto:bearophileHUGS lycos.com">bearoph= ileHUGS lycos.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote= " style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, = 204); padding-left: 1ex;"> I have tried to use the new operators of D2 and I have found several proble= ms. This small program shows two of those problems (some of my problems can= be caused by my improper usage, I&#39;m trying to tell apart the operator = overloading bugs from my improper usage cases).<br> void main() {<br> =A0 =A0Foo f =3D Foo(5);<br> =A0 =A0f++; // line 16<br> =A0 =A0auto a =3D new int[f]; // line 17<br> }<br> <br> Errors:<br> temp2.d(16): Error: var has no effect in expression (__tmp1)<br></blockquot= e><div><br>Try ++f, it works. I guess ++f is rewritten f.opUnary!&quot;++&q= uot;(), but f++ must have create a temporary variable.<br><br>=A0</div><blo= ckquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-le= ft: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> temp2.d(17): Error: cannot implicitly convert expression (f) of type Foo to= uint<br> <br> Note: the line 17 works if I write it this way, but it&#39;s not nice:<br> auto a =3D new int[cast(uint)f];<br> <br></blockquote><div><br>Note the error message: cannot *implicitly* conve= rt expresion (f).<br>opCast defines the explicit cast operation, it has no = effect on implicit casting. Having an opImplicitCast(T) would be nice, I ag= ree.<br> <br>For now, this also does not work:<br><br>void bar(int i) {}<br><br>(in = main:)<br>=A0=A0 bar(f); // Error: cannot implicitly convert expresion (f) = of type Foo to int.<br><br>That&#39;s sad, I&#39;d like to have std.variant= .Variant defining an opCast. That way, you could do:<br> <br>void foo(int i) {}<br>void bar(string s) {}<br><br>Variant v;<br>v =3D = 3;<br>foo(v);=A0=A0=A0=A0=A0=A0 // try to cast v to int implicitly: works, = move along.<br>v =3D &quot;abc&quot;;<br>bar(v);=A0=A0=A0=A0=A0=A0 // impli= cit cast to string, works.<br> <br><br>=A0 Philippe<br><br></div></div> --00032555a4e6da5fde0481c3a2ff--
Mar 14 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Philippe Sigaud:
 Try ++f, it works.

I know, but that's not what I wanted. Thank you to you and Robert Clipsham for your answers, now I present again the same things, plus few others, in the main D newsgroup, to see what they think. Bye, bearophile
Mar 14 2010
prev sibling parent Robert Clipsham <robert octarineparrot.com> writes:
On 14/03/10 13:14, bearophile wrote:
 I have tried to use the new operators of D2 and I have found several problems.
This small program shows two of those problems (some of my problems can be
caused by my improper usage, I'm trying to tell apart the operator overloading
bugs from my improper usage cases).

 Do you know if/how this program can be fixed?


 struct Foo {
      int x;

      Foo opUnary(string op:"++")() {
          this.x++;
          return this;
      }

      uint opCast(T:uint)() {
          return this.x;
      }
 }

 void main() {
      Foo f = Foo(5);
      f++; // line 16
      auto a = new int[f]; // line 17
 }

 Errors:
 temp2.d(16): Error: var has no effect in expression (__tmp1)
 temp2.d(17): Error: cannot implicitly convert expression (f) of type Foo to
uint

 Note: the line 17 works if I write it this way, but it's not nice:
 auto a = new int[cast(uint)f];

 Bye,
 bearophile

I don't know about your first problem, but the latter is because opCast is only for explicit casts. I think implicit casts can be emulated with alias this, eg: ---- alias x this; ---- I'm not sure though as I haven't tested it. This also means that anything that isn't defined in Foo will be forwarded to x though, which might not be what you want.
Mar 14 2010