Sample code:
std::hash_set<int> hs1; // also i try std::unordered_set<int> - same effect
std::hash_set<int> hs2;
hs1.insert(15);
hs1.insert(20);
hs2.insert(20);
hs2.insert(15);
assert(hs1 == hs2);
hash_set doesn't stores elements in some order defined by hash function... why? Please note that this code works in VS2008 using stdext::hash_set.
It looks like equality comparisons are broken for both hash_set
and unordered_set
in Visual C++ 2010.
I implemented a naive equality function for unordered containers using the language from the standard quoted by Matthieu to verify that it's a bug (just to be sure):
template <typename UnorderedContainer>
bool are_equal(const UnorderedContainer& c1, const UnorderedContainer& c2)
{
typedef typename UnorderedContainer::value_type Element;
typedef typename UnorderedContainer::const_iterator Iterator;
typedef std::pair<Iterator, Iterator> IteratorPair;
if (c1.size() != c2.size())
return false;
for (Iterator it(c1.begin()); it != c1.end(); ++it)
{
IteratorPair er1(c1.equal_range(*it));
IteratorPair er2(c2.equal_range(*it));
if (std::distance(er1.first, er1.second) !=
std::distance(er2.first, er2.second))
return false;
// A totally naive implementation of is_permutation:
std::vector<Element> v1(er1.first, er1.second);
std::vector<Element> v2(er2.first, er2.second);
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
if (!std::equal(v1.begin(), v1.end(), v2.begin()))
return false;
}
return true;
}
It returns that hs1
and hs2
from your example are equal. (Somebody let me know if you spot a bug in that code; I didn't really test it extensively...)
I'll file a defect report on Microsoft Connect.
Finally found the reference in the final draft at 23.2.5, note 11:
Two unordered containers
a
andb
compare equal ifa.size() == b.size()
and, for every equivalent-key group[Ea1,Ea2)
obtained froma.equal_range(Ea1)
, there exists an equivalent-key group[Eb1,Eb2)
obtained fromb.equal_range(Ea1)
, such thatdistance(Ea1, Ea2) == distance(Eb1, Eb2)
andis_permutation(Ea1, Ea2, Eb1)
returnstrue
.
I would bet hash_set
is now implemented in term of unordered_set
(to begin with), but I still don't understand why in your case it would fail.
The complexity requirement is O(N) in the average case but degenerates to O(N 2 ) in the worst case because of the linear-chaining implementation requirement.
i ask this question here but give no response =) thanks for your feedback.
i also create some simple console test (just to be sure):
#include <iostream>
#include <hash_set>
int main(int argc, char* argv[])
{
stdext::hash_set<int> hs1, hs2;
hs1.insert(10);
hs1.insert(15);
hs2.insert(15);
hs2.insert(10);
std::cout << ((hs1 == hs2) ? "It works!" : "It NOT works") << std::endl;
return EXIT_SUCCESS;
}
and compile it. using vs2008 command prompt:
cl.exe HashSetTest.cpp /oHashSetTest2008.exe
using vs2010 command prompt:
cl.exe HashSetTest.cpp /oHashSetTest2010.exe
I really see different results =)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.