TDPL: Operator Overloading

Steven Schveighoffer schveiguy at yahoo.com
Wed Aug 25 07:13:01 PDT 2010


On Wed, 25 Aug 2010 10:01:31 -0400, Andrej Mitrovic  
<andrej.mitrovich at gmail.com> wrote:

> Ok I think I am kind of getting this. The template name inside a  
> template is it's instantiation. I can do "CheckedInt.variable" and get  
> back the value of "variable" in the current instantiation.
>
> The trouble is, when you do a call like CheckedInt() you will loose all  
> other data that you had before:
>
> 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.x = 4;
>     bar.x = 5;
>
>     foo = foo + bar;
>    writeln(foo.x);     // writes 0
>     writeln(bar.x);     // writes 5
> }
>
> void main() { }
>
> struct CheckedInt(N) if (isIntegral!N)
> {
>     private N value;
>     int x;
>    this(N value)
>     {
>         this.value = value;
>     }
>
>     // addition
>     CheckedInt opBinary(string op)(CheckedInt rhs) if (op == "+")
>     {
>         auto result = value + rhs.value;
>        enforce(rhs.value >= 0 ? result >= value : result < value);
>         return CheckedInt(result);
>     }
> }
>
> Here I've lost the value of x. "return CheckedInt(result);" calls the  
> constructor of the already instantiated template, but because of the way  
> D works (afaik) it first has to deconstruct the object before  
> constructing it again. And that includes initializing all members to  
> their .init value before calling the constructor.

A struct is a value type, so you are making a copy regardless.   Your  
expectation that foo = ... does not wholly replace foo is incorrect.

You could do this:

this(N value, int x)
{
    this.value = value;
    this.x = x;
}

...

return CheckedInt(result, x);

...

and then you're x comes through.

Value types are always passed by value unless you use pointers or ref.

BTW, this has nothing to do with CheckedInt being a shortcut for  
CheckedInt!N inside the instantiated template.

-Steve


More information about the Digitalmars-d-learn mailing list