TDPL: Operator Overloading

Andrej Mitrovic andrej.mitrovich at whatever.com
Tue Aug 24 15:19:25 PDT 2010


This is a shortened version of some operator overloading code from page 372 (although some code is from pages before it), sorry for the long post:

module binary_ops;

import std.stdio : writeln;
import std.traits;
import std.exception;

unittest
{
    auto foo = CheckedInt!(int)(5);
    auto bar = CheckedInt!(int)(5);
    
    foo = foo + bar;
    writeln(foo.Value);
}

void main()
{
}
 
struct CheckedInt(N) if (isIntegral!N)
{
    private N value;
    
    this(N value)
    {
        this.value = value;
    }
    
    @property
    auto Value()
    {
        return value;
    }
    
    // addition
    CheckedInt opBinary(string op)(CheckedInt rhs) if (op == "+")
    {
        auto result = value + rhs.value;
        
        enforce(rhs.value >= 0 ? result >= value : result < value);
        return result;
    }
}

I don't understand why he's trying to return result here (unless it was a mistake). Result is going to have the type of "private N value", whatever N may be, and this is conflicting with the return type which is CheckedInt. So, this won't compile.

He has the same returns for subtraction and multiplication, but for others like division, shift and bitwise overload he has this:

// division and remainder
    CheckedInt opBinary(string op)(CheckedInt rhs)
    if (op == "/" || op == "%")
    {
        enforce(rhs.value != 0);
        return CheckedInt(mixin("value" ~ op ~ "rhs.value"));
    }

This looks correct. If I change the add overload from the code to this:

// addition
    CheckedInt opBinary(string op)(CheckedInt rhs) if (op == "+")
    {
        auto result = value + rhs.value;
        
        enforce(rhs.value >= 0 ? result >= value : result < value);
        return CheckedInt(mixin("value" ~ op ~ "rhs.value"));
    }

Then the return statement calls a CheckedInt constructor and I get back a CheckedInt struct with the right value in the private variable "value".

What I don't understand is how the constructor can be called like that. In my example the mixin would convert the code to:

return CheckedInt(10);

But if I ever tried a call like "CheckedInt(10)" in a unittest block, it wouldn't work. So how does this magic work?



More information about the Digitalmars-d-learn mailing list