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