www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - struct opCmp confustion

reply Charles Hixson <charleshixsn earthlink.net> writes:
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
next sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
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
parent Charles Hixson <charleshixsn earthlink.net> writes:
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
prev sibling next sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
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
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
  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
prev sibling next sibling parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
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
prev sibling parent "Namespace" <rswhite4 googlemail.com> writes:
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