Opened 11 years ago
Closed 11 years ago
#5711 closed Bugs (fixed)
Equality of unordered containers violates Library requirements
| Reported by: | Owned by: | Daniel James | |
|---|---|---|---|
| Milestone: | To Be Determined | Component: | unordered |
| Version: | Boost 1.47.0 | Severity: | Problem |
| Keywords: | unordered_set unordered_map hash map equality | Cc: |
Description
Both unordered sets and maps have operator==/!= implementations that violate the Library requirements of unordered containers. The following program makes this observable:
#include <iostream>
#include <cstring>
#include <boost/unordered_set.hpp>
struct CharIC {
bool operator()(char c1, char c2) const {
return std::toupper(c1) == std::toupper(c2);
}
std::size_t operator()(char c) const {
return std::toupper(c);
}
};
int main()
{
boost::unordered_set<char, CharIC, CharIC> us1, us2;
us1.insert('a');
us2.insert('A');
std::cout << "us1 == us1: " << (us1 == us1) << std::endl;
std::cout << "us1 != us2: " << (us1 != us2) << std::endl;
}
The second output is:
us1 != us2: 0
instead of the expected
us1 != us2: 1
Reason for this deviation is that the current boost implementation does not additionally test for equality of the container key (which is the value_type for sets). But this is required as of FDIS, [unord.req] p11, where the semantics is defined in terms of the form of std::is_permutation that uses operator== of the iterator value_type. The proper usage of the key equality test is part of the reference implementation of N3068 as well. As far as I read boost/unordered/detail/equivalent.hpp correctly, the same defect applies to the non-unique containers.

This is fixed on trunk. The equality implementation in the released version predates the specification, which is why it doesn't follow it.