digitalmars.D.learn - struct opCmp confustion
- Charles Hixson <charleshixsn earthlink.net> Aug 26 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Aug 26 2012
- Charles Hixson <charleshixsn earthlink.net> Aug 26 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Aug 26 2012
- "Namespace" <rswhite4 googlemail.com> Aug 26 2012
- "Era Scarecrow" <rtcvb32 yahoo.com> Aug 26 2012
- "Namespace" <rswhite4 googlemail.com> Aug 26 2012
Currently the code is:
struct Triplet
{ string wrd1;
string wrd2;
string wrd3;
int val = 1;
int opCmp(ref const Triplet t) const
{ if (wrd1 < t.wrd1) return -1;
if (wrd1 > t.wrd1) return 1;
if (wrd2 < t.wrd2) return -1;
if (wrd2 > t.wrd2) return 1;
if (wrd3 < t.wrd3) return -1;
if (wrd3 > t.wrd3) return 1;
return 0;
//auto i = wrd1.opCmp (t.wrd1);
//if (i != 0) return i;
//i = wrd2.opCmp (t.wrd2);
//if (i != 0) return i;
//return wrd3.opCmp (t.wrd3);
}
}
The commented out code was the original version, which wouldn't compile.
(The current code replaces it.) It gave messages like:
...ser$ rdmd --main -unittest -DdDocs parse1.d
parse1.d(114): Error: undefined identifier 'opCmp'
parse1.d(116): Error: undefined identifier 'opCmp'
parse1.d(118): Error: undefined identifier 'opCmp'
What was I doing wrong?
Aug 26 2012
On Sunday, 26 August 2012 at 16:27:32 UTC, Charles Hixson wrote:Currently the code is: struct Triplet { string wrd1; string wrd2; string wrd3; int val = 1; int opCmp(ref const Triplet t) const { if (wrd1 < t.wrd1) return -1; if (wrd1 > t.wrd1) return 1; if (wrd2 < t.wrd2) return -1; if (wrd2 > t.wrd2) return 1; if (wrd3 < t.wrd3) return -1; if (wrd3 > t.wrd3) return 1; return 0; //auto i = wrd1.opCmp (t.wrd1); //if (i != 0) return i; //i = wrd2.opCmp (t.wrd2); //if (i != 0) return i; //return wrd3.opCmp (t.wrd3); } } The commented out code was the original version, which wouldn't compile. (The current code replaces it.) It gave messages like: ...ser$ rdmd --main -unittest -DdDocs parse1.d parse1.d(114): Error: undefined identifier 'opCmp' parse1.d(116): Error: undefined identifier 'opCmp' parse1.d(118): Error: undefined identifier 'opCmp' What was I doing wrong?
I would think it's you attempting to compare a string. Try using cmp?. untested: import std.algorithm : cmp; struct Triplet { string wrd1, wrd2, wrd3; int opCmp(ref const Triplet t) const { int result1 = cmp(wrd1, t.wrd1); int result2 = cmp(wrd2, t.wrd2); int result3 = cmp(wrd3, t.wrd3); if (result1) return result1; if (result2) return result2; if (result3) return result3; return 0; } }
Aug 26 2012
On 08/26/2012 10:14 AM, Era Scarecrow wrote:On Sunday, 26 August 2012 at 16:27:32 UTC, Charles Hixson wrote:Currently the code is: struct Triplet { string wrd1; string wrd2; string wrd3; int val = 1; ... What was I doing wrong?
I would think it's you attempting to compare a string. Try using cmp?. untested: import std.algorithm : cmp; struct Triplet { string wrd1, wrd2, wrd3; int opCmp(ref const Triplet t) const { int result1 = cmp(wrd1, t.wrd1); int result2 = cmp(wrd2, t.wrd2); int result3 = cmp(wrd3, t.wrd3); if (result1) return result1; if (result2) return result2; if (result3) return result3; return 0; } }
Thank you. So string doesn't respond to opCmp. Pity.
Aug 26 2012
On Sunday, 26 August 2012 at 19:23:10 UTC, Charles Hixson wrote:Thank you. So string doesn't respond to opCmp. Pity.
A string is an array of chars. Structs and Classes have opCmp. You could make a wrapper for the string to include the opCmp then, but that seems irrelevant. Although another option is to make a separate opCmp function that would do it. Tested and works :) import std.algorithm; //simple wrapper int opCmp(string a, string b) { return cmp(a,b); } unittest { assert("abc" < "efg"); assert("efg" > "abc"); assert("abc" == "abc"); }
Aug 26 2012
A string is an array of chars. Structs and Classes have opCmp. You could make a wrapper for the string to include the opCmp then, but that seems irrelevant. Although another option is to make a separate opCmp function that would do it. Tested and works :) import std.algorithm; //simple wrapper int opCmp(string a, string b) { return cmp(a,b); } unittest { assert("abc" < "efg"); assert("efg" > "abc"); assert("abc" == "abc"); }
Maybe I'm wrong but this method is never called by one of these compares. Or is this the point? I wished many times that something like this work, even for other constructs. That would be a way to avoid nasty opCmp, opEquals and so on in the object.d.
Aug 26 2012
On Sunday, 26 August 2012 at 21:45:38 UTC, Namespace wrote:Maybe I'm wrong but this method is never called by one of these compares. Or is this the point?
Mmmm you're right. Due to the re-writing I thought it would work. "abc" < "def" converts to "abc".opCmp("def") < 0, which then doesn't work so it rewrites to opCmp("abc", "def") < 0. Maybe I did it wrong; Or perhaps it's getting the values at compile-time and saving them (less likely).I wished many times that something like this work, even for other constructs. That would be a way to avoid nasty opCmp, opEquals and so on in the object.d.
Well unless whole functionality of certain types are required, writing a compare function for that particular case isn't so bad (or calling it in this case).
Aug 26 2012
On Sunday, 26 August 2012 at 22:57:27 UTC, Era Scarecrow wrote:On Sunday, 26 August 2012 at 21:45:38 UTC, Namespace wrote:Maybe I'm wrong but this method is never called by one of these compares. Or is this the point?
Mmmm you're right. Due to the re-writing I thought it would work. "abc" < "def" converts to "abc".opCmp("def") < 0, which then doesn't work so it rewrites to opCmp("abc", "def") < 0. Maybe I did it wrong; Or perhaps it's getting the values at compile-time and saving them (less likely).I wished many times that something like this work, even for other constructs. That would be a way to avoid nasty opCmp, opEquals and so on in the object.d.
Well unless whole functionality of certain types are required, writing a compare function for that particular case isn't so bad (or calling it in this case).
I prefer implicit calling. ;)
Aug 26 2012









Charles Hixson <charleshixsn earthlink.net> 