www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Operators overloading in D2 again

reply Dan <daniele.niero gmail.com> writes:
Hi everyone,

is there anyway to do this with operators overloading? :


class Tester
{
	double x = 0.0;

	double opBinary(string op:"+")(double value)
	{
		return x+value;
	}

	Tester opBinary(string op:"+")(Tester other)
	{
		Tester ret;
		ret.x += other.x;
		return ret;
	}
}

int main(char[][] args)
{
	Tester t1 = new Tester;
	Tester t2 = new Tester;

	t1.x = 1.0;
	t2.x = 2.0;

	Tester t3;
	t3 = t1+t2;
	assert (t3.x = 3.0);

        return 0;
}


Thanks,
     Dan
May 01 2010
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Dan wrote:
 Hi everyone,
 
 is there anyway to do this with operators overloading? :
 
 
 class Tester
 {
 	double x = 0.0;
 
 	double opBinary(string op:"+")(double value)
 	{
 		return x+value;
 	}
 
 	Tester opBinary(string op:"+")(Tester other)
 	{
 		Tester ret;
 		ret.x += other.x;
 		return ret;
 	}
 }
 
 int main(char[][] args)
 {
 	Tester t1 = new Tester;
 	Tester t2 = new Tester;
 
 	t1.x = 1.0;
 	t2.x = 2.0;
 
 	Tester t3;
 	t3 = t1+t2;
 	assert (t3.x = 3.0);
 
         return 0;
 }
 
 
 Thanks,
      Dan

Functions can not be overloaded by return type alone; so I took the one that returned double out. We are dealing with a Tester class, and it makes sense to me to stay in this type. When necessary, we can provide a conversion function that returns a double value. I've corrected a couple of errors, introduced a constructor, and came up with this: class Tester { double x = 0.0; this(double x) { this.x = x; } Tester opBinary(string op:"+")(const Tester other) const { return new Tester(x + other.x); } } int main(char[][] args) { Tester t1 = new Tester(1.0); Tester t2 = new Tester(2.0); Tester t3 = t1 + t2; assert (t3.x == 3.0); return 0; } Ali
May 01 2010
prev sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 02/05/10 07:14, Dan wrote:
 Hi everyone,

 is there anyway to do this with operators overloading? :

The following code does it: ---- class Tester { double x = 0.0; T opBinary(string op:"+", T)(T value) if(is(T : double)) { return x+value; } T opBinary(string op:"+", T)(T other) if(is(T : Tester)) { Tester ret = new Tester; ret.x = this.x + other.x; return ret; } } int main(char[][] args) { Tester t1 = new Tester; Tester t2 = new Tester; t1.x = 1.0; t2.x = 2.0; Tester t3 = new Tester; t3 = t1+t2; assert (t3.x == 3.0); return 0; } ---- Some variations from the original code: - Fixed the assert ==, not = - Made sure all testers are initialised... Don't forget to instantiate classes before you use them, otherwise you'll end up with segmentation faults - Fixed a semantic error in the latter of the binary functions - an empty Tester is at 0, if you want to add them you need to make sure you do that, not just add other I'd also advise you replace Tester with a struct if you won't be needing inheritance, this way you save some memory overhead, and don't have to remember to use = new Tester; Hope this helps :)
May 02 2010
next sibling parent reply Dan <daniele.niero gmail.com> writes:
Hi,

it certainly helps. However I can't help myself, I still thinking that this is
the most complicated, hard read and to understand way to
overload operators. Maybe there is something I'm missing but I can't really see
the reason of all that. Other languages adopts a much
easier approach, for example python but also C++ that D is trying to surpass
(and it does in most cases) when it comes to operator
overloading is much more clear than D.

I still thinking that the D1's approach was much better than this.

Anyway, now I have another problem: I can't get how to overload operators like
these <=, <, >=, >.
I read the documentation but I can't really understand it.

Thanks for the precious help guys.
      DAniele
May 03 2010
next sibling parent Pelle <pelle.mansson gmail.com> writes:
On 05/03/2010 04:28 PM, Dan wrote:
 Hi,

 it certainly helps. However I can't help myself, I still thinking that this is
the most complicated, hard read and to understand way to
 overload operators. Maybe there is something I'm missing but I can't really
see the reason of all that. Other languages adopts a much
 easier approach, for example python but also C++ that D is trying to surpass
(and it does in most cases) when it comes to operator
 overloading is much more clear than D.

 I still thinking that the D1's approach was much better than this.

The D way is superior, because you don't need to come up with arbitrary names, like the D1/Python way, and it's much easier to parse than the C++-way, at least I think it is.
 Anyway, now I have another problem: I can't get how to overload operators like
these<=,<,>=,>.
 I read the documentation but I can't really understand it.

http://digitalmars.com/d/2.0/operatoroverloading.html#compare You should define an opCmp.
 Thanks for the precious help guys.
        DAniele

May 03 2010
prev sibling parent reply Dan <daniele.niero gmail.com> writes:
I'm still really sceptic, especially because they look to me inconsistent to
each
other.
for example
opBinary(string op:"something here")(Object other)
and then ther is
opCmp(Obejct other)
which is not template and there is only one for all these operators < <= > >=

Did I understand correctly? if I did I found this really inconsistent and in my
experience consistency is better than save lines of code... my personla point of
view, off course.

I'll take you advice anyway and I'll keep going, hopefully I'll change my mind
too. I relly like D so far for pretty much everything, I'm just having hard time
with this operators overloading...

Thanks for you help guys,
     Dan
May 03 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Dan:

 I'm still really sceptic, especially because they look to me inconsistent to
each
 other.

Yes, they seem divided in two groups, with different level of complexity, etc. This is true, and I think this is by design, opCmp and opEquals and few others are useful in many classes. While overloading the []+= operator is for someone that wants to design a new refined data structure, something less common and that requires quite more care. Bye, bearophile
May 03 2010
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Mon, 03 May 2010 14:28:20 +0000, Dan wrote:
 it certainly helps. However I can't help myself, I still thinking that
 this is the most complicated, hard read and to understand way to
 overload operators. Maybe there is something I'm missing but I can't
 really see the reason of all that. Other languages adopts a much easier
 approach, for example python but also C++ that D is trying to surpass
 (and it does in most cases) when it comes to operator overloading is
 much more clear than D.
 
 I still thinking that the D1's approach was much better than this.

I was sceptic at first, too, but after having written some code using the new operator overloading system I am convinced: It totally rocks. It is amazing how much boilerplate code one *doesn't* have to write anymore. Here's a trivial example: struct Pair(T) { T a, b; Pair opBinary(string op)(Pair p) { auto r = this; r.opOpAssign!op(p); return r; } Pair opOpAssign(string op)(Pair p) if (op == "+=" || op == "-=" || op == "*=" || op == "/=") { mixin ("a "~op~" p.a"); mixin ("b "~op~" p.b"); return this; } } With just two short function definitions I have written what would have been eight functions with the old system. For real-life examples, check out: http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/bigint.d http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/complex.d
 Anyway, now I have another problem: I can't get how to overload
 operators like these <=, <, >=, >. I read the documentation but I can't
 really understand it.

Here's an example which (hopefully) illustrates how it works: // Simple struct that wraps a built-in integer. struct Integer { int n; int opCmp(Integer i) { // If this is smaller than i, return a negative number. if (n < i.n) return -1; // If this is equal to i, return zero. else if (n == i.n) return 0; // If this is greater than i, return a positive number. else return 1; } } Of course, this was a needlessly verbose example, as I could just have written this instead: int opCmp(Integer i) { return n - i.n; } This, I guess, is why the signature of opCmp() is the way it is. -Lars
May 03 2010
prev sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Mon, 03 May 2010 16:46:41 +0000, Lars T. Kyllingstad wrote:
         [...]
 
         Pair opBinary(string op)(Pair p)
         {
             auto r = this;
             r.opOpAssign!op(p);

Sorry, that last line should be: r.opOpAssign!(op~"=")(p); -Lars
May 03 2010