Jump to page: 1 2 3
Thread overview
[Bug?] Associative array with class key doesn't work
Feb 11, 2004
Stewart Gordon
Feb 12, 2004
Ivan Senji
Feb 12, 2004
Sean Kelly
Feb 12, 2004
Stewart Gordon
Feb 12, 2004
Sean Kelly
Feb 13, 2004
Stewart Gordon
Feb 13, 2004
Sean Kelly
Feb 13, 2004
Stewart Gordon
Feb 13, 2004
Sean Kelly
Feb 12, 2004
Ivan Senji
Feb 12, 2004
Ilya Minkov
Feb 13, 2004
Manfred Nowak
Feb 14, 2004
Walter
Feb 13, 2004
Vathix
Feb 14, 2004
Walter
Feb 14, 2004
Ivan Senji
Feb 21, 2004
Walter
Feb 21, 2004
Sean Kelly
Feb 16, 2004
Stewart Gordon
Feb 17, 2004
Sean Kelly
Feb 17, 2004
Stewart Gordon
Feb 17, 2004
Sean Kelly
Feb 18, 2004
Stewart Gordon
Feb 18, 2004
Manfred Nowak
Feb 21, 2004
Walter
Feb 22, 2004
Manfred Nowak
[Bug??] Associative array with bit[] key doesn't work too
Feb 14, 2004
Dr.Dizel
[Workaround] Associative array with class key doesn't work
Feb 18, 2004
Stewart Gordon
February 11, 2004
Using DMD 0.79, Windows 98SE.

In the program below, c1 and c2 are equal in just about every respect. So is c3 by the equality definition in the class.  Yet it doesn't consider them to be the same key in aa.  Hence the output is

4
No such element
No such element

Surely it should be looking up the key by actually comparing objects, not just memory addresses?

The same happens if I comment out opEquals and/or toHash, or throw a rehash statement in before the lookups.

Is this a bug, a gotcha, or something else?

Stewart.

----------
import std.c.stdio;
import std.ctype;

class IChar {
	char data;

	this(char d) { data = d; }

	bit opEquals(IChar i) {
		return toupper(data) == toupper(i.data);
	}

	uint toHash() {
		return toupper(data);
	}

	unittest {
		IChar c = new IChar('c');
		IChar d = new IChar('c');
		IChar C = new IChar('C');
		IChar e = new IChar('e');
		assert (c == d);
		assert (c == C);
		assert (c != e);
	}
}

int main() {
	int[IChar] aa;

	IChar c1 = new IChar('c');
	IChar c2 = new IChar('c');
	IChar c3 = new IChar('C');

	aa[c1] = 4;

	if (c1 in aa) {
		printf("%d\n", aa[c1]);
	} else {
		puts("No such element");
	}

	if (c2 in aa) {
		printf("%d\n", aa[c2]);
	} else {
		puts("No such element");
	}

	if (c3 in aa) {
		printf("%d\n", aa[c3]);
	} else {
		puts("No such element");
	}

	return 0;
}

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
February 11, 2004
In article <c0d66a$26hj$1@digitaldaemon.com>, Stewart Gordon says...
>
>Using DMD 0.79, Windows 98SE.
>
>In the program below, c1 and c2 are equal in just about every respect. So is c3 by the equality definition in the class.  Yet it doesn't consider them to be the same key in aa.  Hence the output is
>
>4
>No such element
>No such element
>
>Surely it should be looking up the key by actually comparing objects, not just memory addresses?
>
>The same happens if I comment out opEquals and/or toHash, or throw a rehash statement in before the lookups.
>
>Is this a bug, a gotcha, or something else?
>
>Stewart.
>
>----------
>import std.c.stdio;
>import std.ctype;
>
>class IChar {
>	char data;
>
>	this(char d) { data = d; }
>
>	bit opEquals(IChar i) {
>		return toupper(data) == toupper(i.data);
>	}
>
>	uint toHash() {
>		return toupper(data);
>	}
>
>	unittest {
>		IChar c = new IChar('c');
>		IChar d = new IChar('c');
>		IChar C = new IChar('C');
>		IChar e = new IChar('e');
>		assert (c == d);
>		assert (c == C);
>		assert (c != e);
>	}
>}
>
>int main() {
>	int[IChar] aa;
>
>	IChar c1 = new IChar('c');
>	IChar c2 = new IChar('c');
>	IChar c3 = new IChar('C');
>
>	aa[c1] = 4;
>
>	if (c1 in aa) {
>		printf("%d\n", aa[c1]);
>	} else {
>		puts("No such element");
>	}
>
>	if (c2 in aa) {
>		printf("%d\n", aa[c2]);
>	} else {
>		puts("No such element");
>	}
>
>	if (c3 in aa) {
>		printf("%d\n", aa[c3]);
>	} else {
>		puts("No such element");
>	}
>
>	return 0;
>}
>
>-- 
>My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.


Don't take it as a final word, but maybe it has to do with c1, c2 and c3 being different references.

-------------------
Carlos Santander B.
February 12, 2004
It looks to me too that when the key of the associative array is class type only references are compared and not the objects using the operator==

I had the same problem when trying to implement a set container! First i
used associative array because it was very simple to use but had to give it
up
becouse of this problem!

"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:c0d66a$26hj$1@digitaldaemon.com...
> Using DMD 0.79, Windows 98SE.
>
> In the program below, c1 and c2 are equal in just about every respect. So is c3 by the equality definition in the class.  Yet it doesn't consider them to be the same key in aa.  Hence the output is
>
> 4
> No such element
> No such element
>
> Surely it should be looking up the key by actually comparing objects, not just memory addresses?
>
> The same happens if I comment out opEquals and/or toHash, or throw a rehash statement in before the lookups.
>
> Is this a bug, a gotcha, or something else?
>
> Stewart.
>
> ----------
> import std.c.stdio;
> import std.ctype;
>
> class IChar {
> char data;
>
> this(char d) { data = d; }
>
> bit opEquals(IChar i) {
> return toupper(data) == toupper(i.data);
> }
>
> uint toHash() {
> return toupper(data);
> }
>
> unittest {
> IChar c = new IChar('c');
> IChar d = new IChar('c');
> IChar C = new IChar('C');
> IChar e = new IChar('e');
> assert (c == d);
> assert (c == C);
> assert (c != e);
> }
> }
>
> int main() {
> int[IChar] aa;
>
> IChar c1 = new IChar('c');
> IChar c2 = new IChar('c');
> IChar c3 = new IChar('C');
>
> aa[c1] = 4;
>
> if (c1 in aa) {
> printf("%d\n", aa[c1]);
> } else {
> puts("No such element");
> }
>
> if (c2 in aa) {
> printf("%d\n", aa[c2]);
> } else {
> puts("No such element");
> }
>
> if (c3 in aa) {
> printf("%d\n", aa[c3]);
> } else {
> puts("No such element");
> }
>
> return 0;
> }
>
> --
> My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.


February 12, 2004
Ivan Senji wrote:

> It looks to me too that when the key of the associative array is class type
> only references are compared and not the objects using the operator==
> 
> I had the same problem when trying to implement a set container! First i
> used associative array because it was very simple to use but had to give it
> up becouse of this problem!

Associative containers typically care about equivalence, not equality. ie. in C++ containers the default equivalence rule is less-than, so two objects are considered equivalent if neither is less than the other. Have you tried supplying the other comparison operators?


Sean

February 12, 2004
While it was 2/12/04 4:45 PM throughout the UK, Sean Kelly sprinkled little black dots on a white screen, and they fell thus:

<snip>
> Associative containers typically care about equivalence, not equality. 

But if D's allowing a class as a key type is supposed to be useful, surely it should care about equality?

> ie. in C++ containers the default equivalence rule is less-than, 

Define "C++ container".

> so two objects are considered equivalent if neither is less than the other. 

That would make sense if the associative array were implemented as a binary search tree.  But it shouldn't be trying to do this anyway if it can't be sure first that a comparator is defined.

And anyway, I thought the reason for D having both opCmp and opEquals is so that opEquals can be more efficient for that purpose.  So why should it go out of its way to use opCmp when it should be using opEquals?

> Have you tried supplying the other comparison operators?

Not yet.

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
February 12, 2004
"Sean Kelly" <sean@ffwd.cx> wrote in message news:c0gaj5$185s$1@digitaldaemon.com...
> Ivan Senji wrote:
>
> > It looks to me too that when the key of the associative array is class
type
> > only references are compared and not the objects using the operator==
> >
> > I had the same problem when trying to implement a set container! First i used associative array because it was very simple to use but had to give
it
> > up becouse of this problem!
>
> Associative containers typically care about equivalence, not equality. ie. in C++ containers the default equivalence rule is less-than, so two objects are considered equivalent if neither is less than the other

this makes sense.

> Have you tried supplying the other comparison operators?

I tried writing opCmp for a class that i put in the associative array but ist slill doesnt work the way i think it should and the compiler still compares references!??


>
>
> Sean
>


February 12, 2004
Stewart Gordon wrote:
>
>> ie. in C++ containers the default equivalence rule is less-than, 
> 
> Define "C++ container".

The associative containers I mentioned previously: map, set, etc.

>> so two objects are considered equivalent if neither is less than the other. 
> 
> That would make sense if the associative array were implemented as a binary search tree.  But it shouldn't be trying to do this anyway if it can't be sure first that a comparator is defined.

But the same holds for equality comparison, unless references don't support any other comparison method?

> And anyway, I thought the reason for D having both opCmp and opEquals is so that opEquals can be more efficient for that purpose.  So why should it go out of its way to use opCmp when it should be using opEquals?

I was making assumptions.  I figured the back-end would be implemented as some sort of tree structure for efficiency, which wouldn't be compatible with equality comparisons.


Sean

February 12, 2004
Ivan Senji wrote:
> I tried writing opCmp for a class that i put in the associative array
> but ist slill doesnt work the way i think it should and the compiler
> still compares references!??

I think it's simply a bug since toHash should be enough.

-eye

February 13, 2004
Stewart Gordon wrote:

> Surely it should be looking up the key by actually comparing objects, not just memory addresses?
> 
> The same happens if I comment out opEquals and/or toHash, or throw a rehash statement in before the lookups.
> 

It might be that it's always using getHash from the TypeInfo. I got structs to properly work with associative arrays by making my own TypeInfo. So it looks like a bug.


-- 
Christopher E. Miller
www.dprogramming.com
irc.dprogramming.com #D
February 13, 2004
Ilya Minkov wrote:

> I think it's simply a bug since toHash should be enough.

Agreed. Hashing does not require a (partial) order on the elements.

So long.
« First   ‹ Prev
1 2 3