Thread overview  


March 15 Operator Overloading with multiple return types  

 
Hi everyone, i'm currently working on a small physics engine and I thought it would be a nice feature to overload the operators of my vector struct so I don't have to make ugly function calls just to add and "multiply" my vectors. The problem now is that overloading the addition and subtraction of my vector struct is straight forward because both return and take a vector, dot product is not working for me because it is not possible to overload a function by return type (at least not that I am aware of). My code looks like the one from the dlang docs: Vector opBinary(string op)(Vector rhs) { static if (op == "+") return Vector(this.x + rhs.x, this.y + rhs.y); else static if (op == "") return Vector(this.x  rhs.x, this.y  rhs.y); } As you can see for the dot product the return type has to be a float/double and not a vector. Is there any way to achive this behaivour with D2? The opMul() function is not D2 style and I don't want to use it. Thank you very much, eXodiquas 
March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to eXodiquas  On Friday, 15 March 2019 at 21:35:12 UTC, eXodiquas wrote:
> Is there any way to achive this behaivour with D2?
Yep. Just make the return type in the function declaration `auto`. You are then free to return a different type in each static branch.

March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to Sebastiaan Koppe  On 03/15/2019 02:43 PM, Sebastiaan Koppe wrote:
> On Friday, 15 March 2019 at 21:35:12 UTC, eXodiquas wrote:
>> Is there any way to achive this behaivour with D2?
>
> Yep. Just make the return type in the function declaration `auto`. You are then free to return a different type in each static branch.
Or use template constraints:
struct Vector {
Vector opBinary(string op)(Vector rhs)
if (op == "+") {
return Vector();
}
double opBinary(string op)(Vector rhs)
if (op == "/") {
return 0.5;
}
}
Ali

March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to Ali Çehreli  On Friday, 15 March 2019 at 21:46:50 UTC, Ali Çehreli wrote:
> On 03/15/2019 02:43 PM, Sebastiaan Koppe wrote:
>> On Friday, 15 March 2019 at 21:35:12 UTC, eXodiquas wrote:
>>> Is there any way to achive this behaivour with D2?
>>
>> Yep. Just make the return type in the function declaration `auto`. You are then free to return a different type in each static branch.
>
> Or use template constraints:
>
>
> struct Vector {
> Vector opBinary(string op)(Vector rhs)
> if (op == "+") {
> return Vector();
> }
>
> double opBinary(string op)(Vector rhs)
> if (op == "/") {
> return 0.5;
> }
> }
>
> Ali
Thanks for the quick and simple answers, but I don't get this one. If I do it that way the compiler doesn't know which function to call, or am I doing something wrong?
Vector2 opBinary(string op)(Vector2 rhs) {
if (op == "+") {
return Vector2(this.x + rhs.x, this.y + rhs.y);
} else if (op == "") {
return Vector2(this.x  rhs.x, this.y  rhs.y);
}
}
float opBinary(string op)(Vector2 rhs) {
if (op == "*") {
return this.x * rhs.x + this.y * rhs.y;
}
}
This gives me the error:
overloads (Vector2 rhs) and (Vector2 rhs) both match argument list for opBinary
eXodiquas

March 16 Re: Operator Overloading with multiple return types  

 
Posted in reply to eXodiquas  16.03.2019 1:30, eXodiquas пишет:
> On Friday, 15 March 2019 at 21:46:50 UTC, Ali Çehreli wrote:
>> On 03/15/2019 02:43 PM, Sebastiaan Koppe wrote:
>>> On Friday, 15 March 2019 at 21:35:12 UTC, eXodiquas wrote:
>>>> Is there any way to achive this behaivour with D2?
>>>
>>> Yep. Just make the return type in the function declaration `auto`. You are then free to return a different type in each static branch.
>>
>> Or use template constraints:
>>
>>
>> struct Vector {
>> Vector opBinary(string op)(Vector rhs)
>> if (op == "+") {
>> return Vector();
>> }
>>
>> double opBinary(string op)(Vector rhs)
>> if (op == "/") {
>> return 0.5;
>> }
>> }
>>
>> Ali
>
> Thanks for the quick and simple answers, but I don't get this one. If I do it that way the compiler doesn't know which function to call, or am I doing something wrong?
>
> Vector2 opBinary(string op)(Vector2 rhs) {
> if (op == "+") {
> return Vector2(this.x + rhs.x, this.y + rhs.y);
> } else if (op == "") {
> return Vector2(this.x  rhs.x, this.y  rhs.y);
> }
> }
>
> float opBinary(string op)(Vector2 rhs) {
> if (op == "*") {
> return this.x * rhs.x + this.y * rhs.y;
> }
> }
>
> This gives me the error:
> overloads (Vector2 rhs) and (Vector2 rhs) both match argument list for opBinary
>
> eXodiquas
You add wrong braces (`if` here is part of method signature not its body):
```
Vector2 opBinary(string op)(Vector2 rhs) if (op == "+")
{
return Vector2(this.x + rhs.x, this.y + rhs.y);
}
Vector2 opBinary(string op)(Vector2 rhs) if (op == "")
{
return Vector2(this.x  rhs.x, this.y  rhs.y);
}
float opBinary(string op)(Vector2 rhs) if (op == "*")
{
return this.x * rhs.x + this.y * rhs.y;
}
```

March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to eXodiquas  On Fri, Mar 15, 2019 at 09:35:12PM +0000, eXodiquas via Digitalmarsdlearn wrote: [...] > Vector opBinary(string op)(Vector rhs) > { > static if (op == "+") return Vector(this.x + rhs.x, this.y + rhs.y); > else static if (op == "") return Vector(this.x  rhs.x, this.y  > rhs.y); > } > > As you can see for the dot product the return type has to be a float/double and not a vector. Is there any way to achive this behaivour with D2? The opMul() function is not D2 style and I don't want to use it. [...] Use signature constraints to declare different overloads depending on what the operator is. For example: Vector opBinary(string op)(Vector rhs) if (op == "+"  op == "=") { ... /* implement + and  here */ } double opBinary(string op)(Vector rhs) if (op == "*") { ... /* implement dot product here */ } T  It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horsecart wheels. 
March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to eXodiquas  On Fri, Mar 15, 2019 at 10:30:41PM +0000, eXodiquas via Digitalmarsdlearn wrote: > On Friday, 15 March 2019 at 21:46:50 UTC, Ali Çehreli wrote: [...] > > Or use template constraints: > > > > struct Vector { > > Vector opBinary(string op)(Vector rhs) > > if (op == "+") { > > return Vector(); > > } > > > > double opBinary(string op)(Vector rhs) > > if (op == "/") { > > return 0.5; > > } > > } > > > > Ali > > Thanks for the quick and simple answers, but I don't get this one. If I do it that way the compiler doesn't know which function to call, or am I doing something wrong? > > Vector2 opBinary(string op)(Vector2 rhs) { > if (op == "+") { > return Vector2(this.x + rhs.x, this.y + rhs.y); > } else if (op == "") { > return Vector2(this.x  rhs.x, this.y  rhs.y); > } > } > > float opBinary(string op)(Vector2 rhs) { > if (op == "*") { > return this.x * rhs.x + this.y * rhs.y; > } > } > > This gives me the error: > overloads (Vector2 rhs) and (Vector2 rhs) both match argument list for > opBinary [...] Ali's example was unfortunately deceptively formatted. The `if` has to be *outside* the function body; it's not a regular ifstatement, but a signature constraint. And there is no `else` clause to it. Vector opBinary(string op)(Vector rhs) if (op == '+'  op == '') { /* function body begins here */ ... } double opBinary(string op)(Vector rhs) if (op == '*') { /* function body begins here */ ... } T  Notwithstanding the eloquent discontent that you have just respectfully expressed at length against my verbal capabilities, I am afraid that I must unfortunately bring it to your attention that I am, in fact, NOT verbose. 
March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to H. S. Teoh  On 03/15/2019 03:48 PM, H. S. Teoh wrote:
> On Fri, Mar 15, 2019 at 10:30:41PM +0000, eXodiquas via Digitalmarsdlearn wrote:
>> On Friday, 15 March 2019 at 21:46:50 UTC, Ali Çehreli wrote:
> [...]
>>> Or use template constraints:
>>>
>>> struct Vector {
>>> Vector opBinary(string op)(Vector rhs)
>>> if (op == "+") {
>>> return Vector();
>>> }
>>>
>>> double opBinary(string op)(Vector rhs)
>>> if (op == "/") {
>>> return 0.5;
>>> }
>>> }
>>>
>>> Ali
>>
>> Thanks for the quick and simple answers, but I don't get this one. If
>> I do it that way the compiler doesn't know which function to call, or
>> am I doing something wrong?
>>
>> Vector2 opBinary(string op)(Vector2 rhs) {
>> if (op == "+") {
>> return Vector2(this.x + rhs.x, this.y + rhs.y);
>> } else if (op == "") {
>> return Vector2(this.x  rhs.x, this.y  rhs.y);
>> }
>> }
>>
>> float opBinary(string op)(Vector2 rhs) {
>> if (op == "*") {
>> return this.x * rhs.x + this.y * rhs.y;
>> }
>> }
>>
>> This gives me the error:
>> overloads (Vector2 rhs) and (Vector2 rhs) both match argument list for
>> opBinary
> [...]
>
> Ali's example was unfortunately deceptively formatted.
My editor did that. :)
On my work computer, I've been experimenting with pulling the 'if', 'in', etc to the same level as the function signature:
int foo(T)(T t)
if (isBlah!T)
in (!t.empty) {
// ...
}
Ali

March 15 Re: Operator Overloading with multiple return types  

 
Posted in reply to Ali Çehreli  On Fri, Mar 15, 2019 at 04:29:22PM 0700, Ali Çehreli via Digitalmarsdlearn wrote: > On 03/15/2019 03:48 PM, H. S. Teoh wrote: [...] > > Ali's example was unfortunately deceptively formatted. > > My editor did that. :) This is why I don't trust autoformatters. ;) > On my work computer, I've been experimenting with pulling the 'if', 'in', etc to the same level as the function signature: > > int foo(T)(T t) > if (isBlah!T) > in (!t.empty) { > // ... > } [...] Phobos style also dictates that: int foo(T)(T t) if (isBlah!T) in (!t.empty) { ... } In my own code, however, I find it too blockoftexty, so I prefer to indent it inwards: int foo(T)(T t) if (isBlah!T) in (!t.empty) { ... } But if your style puts { at the end of the line rather than the beginning, this could make it even easier to confuse for a statement inside the body. So YMMV. T  IBM = I'll Buy Microsoft! 
Copyright © 19992018 by the D Language Foundation