digitalmars.D.learn - Operator overloading problem
- Blonder (16/16) Aug 06 2010 Hello,
- Jonathan M Davis (6/27) Aug 06 2010 I think that you need to be more specific with your question. What exact...
- Blonder (13/13) Aug 06 2010 Hello, I am trying to understand how operator overloading works with D. ...
- div0 (49/62) Aug 06 2010 You need to add a second template parameter for the function arguments
- div0 (17/34) Aug 06 2010 And if you are old school C++ and don't like these new fangled template
- Blonder (1/1) Aug 07 2010 Is there a difference (performance) or something else between the two so...
- div0 (9/10) Aug 07 2010 I doubt it, templates are applied at compile time in the front end of
- Philippe Sigaud (16/34) Aug 06 2010 Yes :o(
- Blonder (13/13) Aug 06 2010 Hello,
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;
Aug 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
Aug 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.
Aug 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
Aug 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
Aug 06 2010
Is there a difference (performance) or something else between the two solutions?
Aug 07 2010
On 07/08/2010 16:25, Blonder wrote:Is there a difference (performance) or something else between the two solutions?I doubt it, templates are applied at compile time in the front end of the compiler so the generated code should be the same. The if style syntax allows much more comprehensive restrictions to be placed on the template, but if it's a simple restriction the specialisation looks a bit neater. (well I think so) -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Aug 07 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
Aug 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.
Aug 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
Aug 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.
Aug 06 2010