Jump to page: 1 2
Thread overview
Operator overloading problem
Aug 06, 2010
Blonder
Aug 06, 2010
Jonathan M Davis
Aug 06, 2010
Blonder
Aug 06, 2010
div0
Aug 06, 2010
div0
Aug 07, 2010
Blonder
Aug 07, 2010
div0
Aug 06, 2010
Philippe Sigaud
Aug 06, 2010
Blonder
Aug 06, 2010
div0
Aug 06, 2010
Blonder
August 06, 2010
Hello,

can someone help me with this?

struct Group {
    int i1;
    Group opBinary(string op)(int x) {
        // do somehting
        return this;
    }
    Group opBinary(string op)(Group g) {
        // do something
        return this;
    }
}


Group g, h;
g.i1 = 1;

h = g+g;
August 06, 2010
On Friday, August 06, 2010 12:30:38 Blonder wrote:
> Hello,
> 
> can someone help me with this?
> 
> struct Group {
>     int i1;
>     Group opBinary(string op)(int x) {
>         // do somehting
>         return this;
>     }
>     Group opBinary(string op)(Group g) {
>         // do something
>         return this;
>     }
> }
> 
> 
> Group g, h;
> g.i1 = 1;
> 
> h = g+g;

I think that you need to be more specific with your question. What exactly do you want help with? Are you trying to figure out how operator overloading works? Are you trying to figure out how it would be specifically done in this case? What exactly are you looking for help with?

- Jonathan M Davis
August 06, 2010
Hello, I am trying to understand how operator overloading works with D. I am a C++ programmer and I am reading the book of Andrei Alexandrescu and try to understand D and it's language features.

My Group example don't compile, the error is:
Error: template instance opBinary!("+") matches more than one template
declaration, ...

I know that it matches more than one, that was my intention, because I want to be able to write also

h = g+2 for example.

Is this possible in D?
Can you help me?
Thanks,
Andreas.
August 06, 2010
On 06/08/2010 21:08, Blonder wrote:
> Hello, I am trying to understand how operator overloading works with D. I am a C++
> programmer and I am reading the book of Andrei Alexandrescu and try to understand
> D and it's language features.
>
> My Group example don't compile, the error is:
> Error: template instance opBinary!("+") matches more than one template
> declaration, ...
>
> I know that it matches more than one, that was my intention, because I want to be
> able to write also
>
> h = g+2 for example.
>
> Is this possible in D?
> Can you help me?
> Thanks,
> Andreas.


You need to add a second template parameter for the function arguments and add a template constrait like so:

struct Group {
    int i1;

    Group opBinary(string op, U) (U x)
		if(op == "+" && is(U: int))
	{
        // do somehting
        return this;
    }

	Group opBinary(string op, U) (U rhs)
		if(op == "+" && is(U: Group))
	{
        // do something
        return this;
    }
}


void main() {
	Group g, h;
	g.i1 = 1;

	h = g+g;
}

Personally, I'm with you and I would expect that the compiler should example the function parameters after the template string parameter but it doesn't.

It's important to note: you must use the template parameter U, you can not explitictly use the type (int/Group) like you can in C++.

ie you can't do:

struct Group {
    int i1;

    // DOES NOT WORK
    Group opBinary(string op, U) (int x)
		if(op == "+" && is(U: int))
	{
        // do somehting
        return this;
    }

    // DOES NOT WORK
    Group opBinary(string op, U) (Group rhs)
		if(op == "+" && is(U: Group))
	{
        // do something
        return this;
    }
}

--
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
August 06, 2010
On 06/08/2010 21:37, div0 wrote:
>
>
> You need to add a second template parameter for the function arguments
> and add a template constrait like so:
>
> struct Group {
>     int i1;
>
>     Group opBinary(string op, U) (U x)
>     if(op == "+" && is(U: int))
>     {
> 	// do somehting
> 	return this;
>     }
>
>     Group opBinary(string op, U) (U rhs)
>     if(op == "+" && is(U: Group))
>     {
> 	// do something
> 	return this;
>     }
> }

And if you are old school C++ and don't like these new fangled template constraints you can use specialisation as well:

struct Group {
    int i1;

    Group opBinary(string op : "+", U: int) (U x) {
        // do somehting
        return this;
    }

    Group opBinary(string op : "+", U: Group) (U rhs) {
        // do something
        return this;
    }
}


-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
August 06, 2010
On Fri, Aug 6, 2010 at 22:37, div0 <div0@sourceforge.net> wrote:

> Personally, I'm with you and I would expect that the compiler should example the function parameters after the template string parameter but it doesn't.
>

Yes :o(
You need to add a second template parameter for the function arguments and
add a template constrait like so:


> struct Group {
>    int i1;
>
>    Group opBinary(string op, U) (U x)
>                if(op == "+" && is(U: int))
>        {
>        // do somehting
>        return this;
>    }
>
>        Group opBinary(string op, U) (U rhs)
>                if(op == "+" && is(U: Group))
>        {
>        // do something
>        return this;
>    }
> }
>
>
In some cases, you might factor things a bit:

Group opBinary(string op, U)(U u) if (op == "+")
{
   common code for all U's;

    static if (some test on U)
      some code;
   else
     other code;
}

Maybe  some code is common between the Group case and the int case. I'm not sure it's more readable this way...

Philippe


August 06, 2010
Hello,

this seems to work, but if I add the following

	double opBinary(string op, U) (U rhs)
	{
		static if(op == "^" && is(U: Group))
		{
			// do something
			return 42;
		}
	}

because I want to write the following: double d = g^h;
I have the same problem again.

This syntax isn't very intuitive.
August 06, 2010
On 06/08/2010 22:24, Blonder wrote:
> Hello,
>
> this seems to work, but if I add the following
>
> 	double opBinary(string op, U) (U rhs)
> 	{
> 		static if(op == "^"&&  is(U: Group))
> 		{
> 			// do something
> 			return 42;
> 		}
> 	}
>
> because I want to write the following: double d = g^h;
> I have the same problem again.

You should only use the static if on the 2nd template parameter.
You want:

class Group {
	void	opBinrary(string op, U)(U rhs)
	if(op == "^") {
	}

	void	opBinrary(string op, U)(U rhs)
	if(op == "+") {
	}

	void	opBinrary(string op, U)(U rhs)
	if(op == "-") {
	}

	void	opBinrary(string op, U)(U rhs)
	if(op == "*") {
	}
}

Note that the 'if' is a template constraint is and part of the template signature; this is what stops you getting multiple matches when trying to determine which template to use.

You can only use the static if inside the function if all the types U are similar, otherwise you'll get conversion problems with return values and such.

>
> This syntax isn't very intuitive.
>

No programming language is intuitive; they all take time to learn.
D is a big win over C++ though and well worth sticking with.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
August 06, 2010
Thanks, that is the solution.

> No programming language is intuitive; they all take time to learn. D is a big win over C++ though and well worth sticking with.

Yes, you are right, it takes time to learn.

@Philippe Sigaud
Thanks also.
August 07, 2010
Is there a difference (performance) or something else between the two solutions?
« First   ‹ Prev
1 2