www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - boxing, struct opAssign and constructors

reply gena <gbatyan gmail.com> writes:
Let's say I have some boxing implementation using structs.

With D1 one could have

struct Value {
   Value opAssign(double arg){...}
}

Value v1, v2;
v1 = v2;


With D2 (at least 014 and 023) I get compilation error:
function Value.opAssign (double arg) does not match parameter types (Value)

This sounds like as soon as you have at least one opAssign you MUST 
write the 'copy-constructor-like' version of opAssign
BTW, what's the right jargon for such 'reflective' opAssign?

Why not giving an OPTION to let compiler create the fastest 
copy-ctor-like opAssign automatically, as it does if I haven't defined 
any opAssigns?


-------------------------------
having the above struct definition,

Value v = 10

gives compilation error:
Error: cannot cast int to Value[]

why no line number in error?
Where does [] assumption come from?

whereas

Value v = 10.0
gives
test.d(25): Error: cannot cast double to Value

and finally

Value v; v = 10;
Value v; v = 10.0;

do compile and work the same.

NOTE: there is NO opAssign for int, only for double and Value.

-------------------------------
I couldn't find other way of calling struct constructors except using 
new operator, shouldn't there be a way to do the same on stack? Say

struct Value {
   this(double arg) {...}
}

Value v(10)
AND/OR maybe the above
Value v = 10
to be interpreted as calling the constructor?

right now only following initializer seems to work:
Value v; v = 10;
But It's ugly and I tend to question the efficiency of the produced code
Feb 14 2009
parent Sergey Gromov <snake.scaly gmail.com> writes:
Sat, 14 Feb 2009 15:25:23 +0200, gena wrote:

 struct Value {
    Value opAssign(double arg){...}
 }
 
 Value v1, v2;
 v1 = v2;
 
 With D2 (at least 014 and 023) I get compilation error:
 function Value.opAssign (double arg) does not match parameter types (Value)

The D2 specification seems inconsistent. The operator overloading states, | The assignment operator = can be overloaded if the lvalue is a struct | aggregate, and opAssign is a member function of that aggregate. The | assignment operator cannot be overloaded for rvalues that can be | implicitly cast to the lvalue type. http://www.digitalmars.com/d/2.0/operatoroverloading.html#Assignment However, the Structs documentation says otherwise: | While the compiler will generate a default opAssign as needed, a | user-defined one can be supplied. The user-defined one must still | implement the equivalent semantics, but can be more efficient. http://www.digitalmars.com/d/2.0/struct.html#AssignOverload Even considering the latter, the specs are still promising to provide a default opAssign so that v1 = v2 should still work. I think it's a bug, either in the documentation, in compiler implementation, or both.
 -------------------------------
 having the above struct definition,
 
 Value v = 10
 
 gives compilation error:
 Error: cannot cast int to Value[]
 
 why no line number in error?
 Where does [] assumption come from?
 
 whereas
 
 Value v = 10.0
 gives
 test.d(25): Error: cannot cast double to Value
 
 and finally
 
 Value v; v = 10;
 Value v; v = 10.0;
 
 do compile and work the same.
 
 NOTE: there is NO opAssign for int, only for double and Value.

I have no idea what's going on here. Note though that struct specs mentioned above say that copy-construction is automatically taken care about, and only assignment semantics can be overloaded to provide for more efficient implementations.
 -------------------------------
 I couldn't find other way of calling struct constructors except using 
 new operator, shouldn't there be a way to do the same on stack? Say
 
 struct Value {
    this(double arg) {...}
 }
 
 Value v(10)
 AND/OR maybe the above
 Value v = 10
 to be interpreted as calling the constructor?
 
 right now only following initializer seems to work:
 Value v; v = 10;
 But It's ugly and I tend to question the efficiency of the produced code

The canonical way seems to be auto v = Value(10);
Feb 15 2009