Re: the behavior of opAssign

2018-01-29 Thread Sobaya via Digitalmars-d-learn

On Monday, 29 January 2018 at 10:06:23 UTC, Simen Kjærås wrote:

On Monday, 29 January 2018 at 09:23:55 UTC, Sobaya wrote:

I found a strange behavior.

class A {
void opAssign(int v) {}
}

class Test {
A a;
this() {
a = new A(); // removing this causes compile error.
a = 3; // cannot implicitly convert expression `3` of 
`int` to `A`

}
}

void main() {
// this is allowed.
A a;
a = 3;
}


The first assignment in the constructor isn't actually a call 
to opAssign, it's a constructor call. In the same way, this 
will not compile:


A a = 3;

Also, since classes are reference types, you will need to 
construct an instance before assigning an int to it. The code 
in your main() will crash at runtime because the 'this' 
reference is null inside opAssign.


--
  Simen


I have not read https://dlang.org/spec/class.html
In 15.9, there is an explanation about it.
Sorry.

--
  Sobaya


Re: the behavior of opAssign

2018-01-29 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 29 January 2018 at 09:23:55 UTC, Sobaya wrote:

I found a strange behavior.

class A {
void opAssign(int v) {}
}

class Test {
A a;
this() {
a = new A(); // removing this causes compile error.
a = 3; // cannot implicitly convert expression `3` of 
`int` to `A`

}
}

void main() {
// this is allowed.
A a;
a = 3;
}


The first assignment in the constructor isn't actually a call to 
opAssign, it's a constructor call. In the same way, this will not 
compile:


A a = 3;

Also, since classes are reference types, you will need to 
construct an instance before assigning an int to it. The code in 
your main() will crash at runtime because the 'this' reference is 
null inside opAssign.


--
  Simen


Re: the behavior of opAssign

2018-01-29 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, January 29, 2018 09:23:55 Sobaya via Digitalmars-d-learn wrote:
> I found a strange behavior.
>
> class A {
>  void opAssign(int v) {}
> }
>
> class Test {
>  A a;
>  this() {
>  a = new A(); // removing this causes compile error.
>  a = 3; // cannot implicitly convert expression `3` of
> `int` to `A`
>  }
> }
>
> void main() {
>  // this is allowed.
>  A a;
>  a = 3;
> }
>
> Is it a compiiler's bug?

I don't think so. The first "assignment" is actually initialization, not
assignment. opAssign is for assigning to a value that was already
initialized.

- Jonathan M Davis



the behavior of opAssign

2018-01-29 Thread Sobaya via Digitalmars-d-learn

I found a strange behavior.

class A {
void opAssign(int v) {}
}

class Test {
A a;
this() {
a = new A(); // removing this causes compile error.
a = 3; // cannot implicitly convert expression `3` of 
`int` to `A`

}
}

void main() {
// this is allowed.
A a;
a = 3;
}

Is it a compiiler's bug?


Strange behavior with opAssign and static if

2014-02-08 Thread Andre

Hi,

I have a template structure Decimal which is used in a OrderDb 
structure. The opAssign method in Decimal leads to strange

behavior in the function execute();

The function execute stores the values of OrderDb in a variant
array. Decimals value should be stored as strings. There is
a static if for this condition.

There is a compilation error for the line
arr[i] = __traits(getMember, struc, member);

- function.main.OrderDb.opAssign (OrderDb p) is not callable using 
argument types ()


This compilation error disappears if I remove the opAssign method
in Decimal.

How can the opAssign of Decimal influence the code path for a non
decimal field?

Kind regards
André

---code---

import std.traits: isInstanceOf;
import std.variant;

struct Decimal(int precision, int scale){
void opAssign(T)(T d)
if (isInstanceOf!(Decimal, T)){}

string toString(){return 10.22;};
}

struct OrderDb{
string orderId;
Decimal!(10,2) amount;
}

void main(){
execute(OrderDb());
}

void execute(T)(T struc){
Variant[] arr = new Variant[](2);

foreach (i, member;__traits(allMembers, T)){
		static if (isInstanceOf!(Decimal, typeof(__traits(getMember, struc, 
member{

// Store decimals as string
arr[i] = (__traits(getMember, struc, 
member)).toString();
} else {
// Store other values with their types
arr[i] = __traits(getMember, struc, member);
}
}
}


Re: Strange behavior with opAssign and static if

2014-02-08 Thread Stanislav Blinov
__traits(allMembers) gives you *all* members, including methods 
(even implicit).
As soon as you define opAssign for your Decimal, it gets defined 
for OrderDb too, and then you try to assign to it :)


What you need is something like this:

void execute(T)(T struc){
Variant[] arr = new Variant[](2);

foreach(i, member; struc.tupleof) {
static if (isInstanceOf!(Decimal, typeof(member))){
// Store decimals as string
arr[i] = member.toString();
} else {
// Store other values with their types
arr[i] = member;
}
}
}




Re: Strange behavior with opAssign and static if

2014-02-08 Thread Andre

Thanks a lot!
This works great.

Am 08.02.2014 14:27, schrieb Stanislav Blinov:

__traits(allMembers) gives you *all* members, including methods (even
implicit).
As soon as you define opAssign for your Decimal, it gets defined for
OrderDb too, and then you try to assign to it :)

What you need is something like this:

void execute(T)(T struc){
 Variant[] arr = new Variant[](2);

 foreach(i, member; struc.tupleof) {
 static if (isInstanceOf!(Decimal, typeof(member))){
 // Store decimals as string
 arr[i] = member.toString();
 } else {
 // Store other values with their types
 arr[i] = member;
 }
 }
}