www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - No implicit opOpAssign for structs with basic types?

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
D doesn't have implicit operators for structs?

struct S {float a, float b};
S a = {1, 5};
S b = {2, 5);

a += b;
Error: a is not a scalar, it is a S

So I really have to write an overloaded operator for such cases?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster
Apr 04 2020
next sibling parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Saturday, 4 April 2020 at 10:22:29 UTC, Robert M. Münch wrote:
 D doesn't have implicit operators for structs?

 struct S {float a, float b};
 S a = {1, 5};
 S b = {2, 5);

 a += b;
 Error: a is not a scalar, it is a S

 So I really have to write an overloaded operator for such cases?
Probably I didn't understand what you mean. Sorry if this is not the case, but this one is easy. ... struct S { float a; float b; S opOpAssign(string op)(ref S rhs) if (op == "+"){ this.a += rhs.a; this.b += rhs.b; return this; } } void main() { S a = {1, 5}; S b = {2, 5}; a += b; writeln(a); } ...
Apr 04 2020
next sibling parent reply =?utf-8?Q?Robert_M._M=C3=BCnch?= <robert.muench saphirion.com> writes:
On 2020-04-04 10:32:32 +0000, Ferhat KurtulmuÅŸ said:

 Probably I didn't understand what you mean. Sorry if this is not the 
 case, but this one is easy.
 ...
 struct S {
      float a;
      float b;
 
      S opOpAssign(string op)(ref S rhs) if (op == "+"){
          this.a += rhs.a;
          this.b += rhs.b;
          return this;
      }
 }
 
 
 void main()
 {
      S a = {1, 5};
      S b = {2, 5};
 
      a += b;
 
      writeln(a);
 }
 ...
Yes, sure, but in C++ I don't have to explicitly write this down. It just works. IMO that makes a lot of sense as long as all types fit. This just looks superfluously. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Apr 04 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/4/20 8:07 AM, Robert M. Münch wrote:
 On 2020-04-04 10:32:32 +0000, Ferhat KurtulmuÅŸ said:
 
 Probably I didn't understand what you mean. Sorry if this is not the 
 case, but this one is easy.
 ...
 struct S {
      float a;
      float b;

      S opOpAssign(string op)(ref S rhs) if (op == "+"){
          this.a += rhs.a;
          this.b += rhs.b;
          return this;
      }
 }


 void main()
 {
      S a = {1, 5};
      S b = {2, 5};

      a += b;

      writeln(a);
 }
 ...
Yes, sure, but in C++ I don't have to explicitly write this down. It just works. IMO that makes a lot of sense as long as all types fit. This just looks superfluously.
steves homebuild:~$ cat test.cpp struct S { float a; float b; }; int main() { S a = {1, 5}; S b = {2, 5}; a += b; } steves homebuild:~$ g++ -o test test.cpp test.cpp: In function ‘int main()’: test.cpp:11:4: error: no match for ‘operator+=’ (operand types are ‘S’ and ‘S’) a += b; ~~^~~~ Doesn't seem to "just work" for me... -Steve
Apr 04 2020
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/4/20 8:45 AM, Steven Schveighoffer wrote:

 Yes, sure, but in C++ I don't have to explicitly write this down. It
 just works. IMO that makes a lot of sense as long as all types fit.
 This just looks superfluously.
steves homebuild:~$ cat test.cpp struct S { float a; float b; }; int main() { S a =3D {1, 5}; S b =3D {2, 5}; a +=3D b; } steves homebuild:~$ g++ -o test test.cpp test.cpp: In function =E2=80=98int main()=E2=80=99: test.cpp:11:4: error: no match for =E2=80=98operator+=3D=E2=80=99 (ope=
rand types are =E2=80=98S=E2=80=99
 and =E2=80=98S=E2=80=99)
    a +=3D b;
    ~~^~~~

 Doesn't seem to "just work" for me...
I was about to say the same. C++ does not have this feature. What it has = as a feature and as a guideline is to define an operator+ outside of the = type's definition. Perhaps that's what's helping in C++ in this case:=20 the type looks clean but there are "interface" functions outside of it. I've used the following trick in D for many of my types, which I've been = copy-pasting but it can be mixed in: struct S { float a; float b; int opCmp(const(typeof(this)) that) const { import std.typecons : tuple; return tuple(this.tupleof).opCmp(tuple(that.tupleof)); } } unittest { assert(S(3) < S(4)); assert(S(1, 2) > S(1, 1)); } void main() { } Ali
Apr 04 2020
prev sibling parent reply =?utf-8?Q?Robert_M._M=C3=BCnch?= <robert.muench saphirion.com> writes:
On 2020-04-04 10:32:32 +0000, Ferhat KurtulmuÅŸ said:

 struct S {
      float a;
      float b;
 
      S opOpAssign(string op)(ref S rhs) if (op == "+"){
          this.a += rhs.a;
          this.b += rhs.b;
          return this;
      }
 }
If the struct is from some 3rd party source, how can I add such an operator overloading to it? Is it possible to "extend" a struct later? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Apr 04 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/4/20 8:14 AM, Robert M. Münch wrote:
 On 2020-04-04 10:32:32 +0000, Ferhat KurtulmuÅŸ said:
 
 struct S {
      float a;
      float b;

      S opOpAssign(string op)(ref S rhs) if (op == "+"){
          this.a += rhs.a;
          this.b += rhs.b;
          return this;
      }
 }
If the struct is from some 3rd party source, how can I add such an operator overloading to it? Is it possible to "extend" a struct later?
No. operators must be implemented by the type itself. That is intentional (so types always act the same no matter where you import them). The only exception is UFCS, which doesn't cover operator overloading. However, you can make a wrapper and use alias this. -Steve
Apr 04 2020
prev sibling parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Saturday, 4 April 2020 at 12:14:23 UTC, Robert M. Münch wrote:
 On 2020-04-04 10:32:32 +0000, Ferhat KurtulmuÅŸ said:

 struct S {
      float a;
      float b;
 
      S opOpAssign(string op)(ref S rhs) if (op == "+"){
          this.a += rhs.a;
          this.b += rhs.b;
          return this;
      }
 }
If the struct is from some 3rd party source, how can I add such an operator overloading to it? Is it possible to "extend" a struct later?
Oh I see what you mean now. In JavaScript you can for instance extend Array with an user defined method like; Array.prototype.insert = function(index) { ... return this; }; Of course in d CTFE helps for similar cases. But I am afraid operator overloading outside struct/class body is not available in D. It would be nice feature though.
Apr 04 2020
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Saturday, April 4, 2020 4:22:29 AM MDT Robert M. Münch via Digitalmars-d-
learn wrote:
 D doesn't have implicit operators for structs?

 struct S {float a, float b};
 S a = {1, 5};
 S b = {2, 5);

 a += b;
 Error: a is not a scalar, it is a S

 So I really have to write an overloaded operator for such cases?
You could just use the constructor syntax. e.g. S a = S(1, 5); S b = S(2, 5); - Jonathan M Davis
Apr 04 2020