Usually (as in C++), the hash function returns any size_t value — thus many different hash values are possible (2^32).
That is why I always thought that when people talked about them being implemented as tables, that is not really true in practice because the table would be much too big (2^32 entries). Of course my assumption was wrong that the table must be as big as the full range of hash values.
It seems that the actual implementation is more difficult than I thought. What I always had in mind, what would be the naive implementation, is something like:
typedef list< pair<Key,Value> > Bucket;
typedef map< size_t, Bucket > Hashtable;
Now my question: How does this naive implementation differs from actual implementations in the praxis in terms of complexity (runtime and memory)?
Note that there are other ways to implement hash tables as Matthieu M points out. The remainder of this answer assumes that you want to use hashing with buckets made of some kind of list.
Assuming you are talking about time complexity.
Hash tables are expected to have O(1) best-case access. Your proposal for implementation in the question uses a
map<size_t,Bucket>for access to the buckets which would result in O(log n) time complexity. You need something with O(1) access time complexity, such as avector<Bucket>to comply with the expected time complexity of a hash table.More details
Hash tables can vary between having excellent and poor time complexity, depending on how sparsely populated they are.
In the best case, each bucket has at most one entry, and access by key is O(1). This is the commonly quoted complexity for hash tables.
In the worst case, each key has the same hash value, and access by key is effectively searching a list which results in O(n) behaviour.
Real-world use is usually somewhere between these extremes, hopefully closer towards O(1).
The accepted answer to your other question has some simplified code you can use to work through these two extremes to satisfy yourself that this is the case.