Re: Generic compare function
On Jan 8, 7:44 am, Goran <goran.pu...@gmail.com> wrote:
On Jan 8, 8:51 am, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
You can see in the following STL code from VS2008 that the _Pred()
function is being invoked twice for a comparison:
template<class _Pr, class _Ty1, class _Ty2> inline
bool __CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, const _Ty1& _Left,
const _Ty2& _Right,
const wchar_t *_Where, unsigned int _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
if (!_Pred(_Left, _Right))
return (false);
else if (_Pred(_Right, _Left))
_DEBUG_ERROR2("invalid operator<", _Where, _Line);
return (true);
}
Hmmm... I think MS people should check this. That second comparison
should be out of the picture in optimized builds, because it only has
debugging purposes. Quick look at sources tells me that ain't the
case. Implementation quality issue?
I do not understand the standard library very well, but it looks like
this is more a deliberate design issue than implementation issue:
http://www.sgi.com/tech/stl/less.html
Apparently, the idea is that, if A < B, then logically, B must be
greater than A, so the designers of standard library help the
programmer by requiring that s/he only supply operator <, and the
library will take care of the rest.
As Adam pointed out, this "taking care of the rest" is the crux of the
issue.
By prescribing that comparisons must rely on operator <, and not (-,
0, +), the double-comparison for testing order becomes inevitable.
On a semi-related note regarding a fat string class to conform to the
model Adam proposes, whereby comparison of two strings is done using
only state entirely contained within either string:
int s = signum(s1, s2); // s becomes (+, 0, -)
....I realized this morning that all my fretting to keep such a String
class "skinny" compared to std::string might be unwarranted. I figured
that, while my String was guaranteed to be fat, std::string might not
be so skinny itself.
So I checked:
int main ()
{
cout << "sizeof(String) == " << sizeof(String) << endl;
cout << "sizeof(std::string) == " << sizeof(std::string) << endl;
}
Output Debug Mode, Visual Studio 2008:
sizeof(String) == 28
sizeof(std::string) == 32
Output Release Mode, Visual Studio 2008:
sizeof(String) == 28
sizeof(std::string) == 28
Of course, there will be trade-offs. I imagine my String will be
slower in some situations and might not provide some desirable
feautures of std::string, but at least this shows thave a sizeof
(A_String_Class) >, say, 12, is not so bad.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]