2006-02-26 19:03:11 +00:00
|
|
|
[section:comparison Comparison to Associative Containers]
|
|
|
|
|
|
|
|
The unordered associative containers have a very similar interface to the
|
|
|
|
associative containers. For example:
|
|
|
|
|
|
|
|
#include <boost/unordered_map.hpp>
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
typedef ``[classref boost::unordered_map]``<std::string, int> map;
|
|
|
|
map x;
|
|
|
|
x["one"] = 1;
|
|
|
|
x["two"] = 2;
|
|
|
|
x["three"] = 3;
|
|
|
|
|
|
|
|
std::cout<<x["one"]<<"\n"; // Outputs '1'
|
|
|
|
std::cout<<x["missing"]<<"\n"; // Outputs '0' - the default value
|
|
|
|
|
|
|
|
But a major difference is that the elements aren't ordered, so:
|
|
|
|
|
|
|
|
BOOST_FOREACH(map::value_type i, x) {
|
|
|
|
std::cout<<i.first<<","<<i.second<<"\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
might output:
|
|
|
|
|
|
|
|
two,2
|
|
|
|
one,1
|
|
|
|
three,3
|
2006-03-14 22:41:39 +00:00
|
|
|
missing,0
|
2006-02-26 19:03:11 +00:00
|
|
|
|
2006-03-14 22:41:39 +00:00
|
|
|
or the same elements in any other order. If `std::set` was used it would always
|
|
|
|
be ordered lexicographically.
|
2006-02-26 19:03:11 +00:00
|
|
|
|
|
|
|
The containers automatically grow as more elements are inserted, this can cause
|
|
|
|
the order to change and iterators to be invalidated (unlike associative
|
|
|
|
containers whose iterators are only invalidated when their elements are
|
|
|
|
erased).
|
|
|
|
|
2006-03-14 22:41:39 +00:00
|
|
|
In the STL, the comparion operators for containers are defined in terms
|
|
|
|
of comparing the sequence of elements. As the elements' order is unpredictable
|
|
|
|
this would be nonsensical, so the comparison operators aren't defined.
|
2006-02-26 19:03:11 +00:00
|
|
|
|
2006-03-14 22:41:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
[endsect]
|
|
|
|
|
|
|
|
[section Equality Predicates and Hash Functions]
|
2006-02-26 19:03:11 +00:00
|
|
|
|
|
|
|
[/TODO: A better introduction to hash functions?]
|
|
|
|
|
|
|
|
While the associative containers use an ordering relation to specify how the
|
|
|
|
elements are stored, the unordered associative containers use an equality
|
|
|
|
predicate and a hash function. For example [classref boost::unordered_set]
|
|
|
|
is declared as:
|
|
|
|
|
|
|
|
template<typename Value,
|
|
|
|
typename Hash = ``[classref boost::hash]``<Value>,
|
|
|
|
typename Pred = std::equal_to<Value>,
|
|
|
|
typename Alloc = std::allocator<Value> >
|
|
|
|
class ``[classref boost::unordered_set unordered_set]``;
|
|
|
|
|
|
|
|
The hash function comes first as you might want to change the hash function
|
|
|
|
but not the equality predicate, while if you were to change the behaviour
|
|
|
|
of the equality predicate you would have to change the hash function to match
|
|
|
|
it.
|
|
|
|
|
|
|
|
For example, if you wanted to use
|
|
|
|
|
|
|
|
[endsect]
|