opUnary overloading

Ali Çehreli acehreli at yahoo.com
Sun Aug 26 13:55:46 PDT 2012


On 08/26/2012 01:33 PM, cal wrote:
>
> I have a struct wrapping a union of an int and a float, and want to
> overload opUnary for this struct:
>
> struct Value
> {
> enum Type {
> INT, FLOAT
> }
>
> Type type;
>
> union {
> int i;
> float f;
> }
>
> this(int _i) {
> i = _i;
> type = Type.INT;
> }
>
> this(float _f) {
> f = _f;
> type = Type.FLOAT;
> }
>
> auto opUnary(string s)() if (s == "-") {
> if (type == Type.INT)
> return -i;
> if (type == Type.FLOAT) // If i comment this out, I get an int back
> return -f; // as expected
> assert(0);
> }
> }
>
> Value v1 = Value(25);
> assert(v1.type == Value.Type.INT);
> auto neg = -v1;
> writeln(typeof(neg).stringof); // this returns float, when it should
> return int
>
> The part I don't understand is this: in the opUnary method, if I comment
> out the second if conditional (if (type == Type.FLOAT)) then when doing
> the negation on v1 I get an INT as expected. If I don't comment this
> code out, I get a float.
>
> When commented out, I get back -25 as an int, which i expect. When not
> commented out, I get back -nan, which suggests to me that it is
> returning the (uninitialized) float from the union, not simply giving me
> back the int as a float.
>
> Could someone explain this?

opUnary should return Value:

     Value opUnary(string s)() if (s == "-") {
         final switch (type) with (Type) {
         case INT:
             return Value(-i);

         case FLOAT:
             return Value(-f);
         }
     }

I have also taken advantage of

- 'final switch' to obviate the assert(0)

- 'with' to simplify syntax (no need to be explicit as in 'Type.INT' 
anymore)

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html


More information about the Digitalmars-d-learn mailing list