Implementation of a Hash Map in C++ I created a templated Hash Map class in C++, which supports most of the basic C++ types (e.g. int, float, char...). I would like some feedback regarding my implementation and what is bad and can be improved.

#ifndef _LIB_HASHMAP
#define _LIB_HASHMAP
#include &lt;exception&gt;
#include &lt;string&gt;

namespace lib{

    namespace details{

        unsigned int generate_hash(const int&amp; key, const size_t&amp; hash_map_size){
            return key%hash_map_size;
        }

        unsigned int generate_hash(const std::string&amp; key, const size_t&amp; hash_map_size){
            return key.size()%hash_map_size;
        }

        unsigned int generate_hash(const char* key, const size_t&amp; hash_map_size){
            size_t position = 0;
            for (size_t i=0; key[i]!='\0'; i++){
                position += key[i];
            }
            return position%hash_map_size;
        }

    }


    template &lt;typename T, typename U&gt;
    class hash_map{

    private:
        struct hash_entry{
            T key;
            U value;
            hash_entry(){}
            hash_entry(const T&amp; _key, const U&amp; _value)
                : key(_key), value(_value){}
        };
        hash_entry* hash_entries;
        unsigned int* filled_positions;
        unsigned int hash_map_size;
        unsigned int num_entries;

    public:
        typedef const hash_entry* const_iterator;
        typedef hash_entry* iterator;
        explicit hash_map(unsigned int);
        ~hash_map();
        iterator begin();
        iterator end();
        const_iterator cbegin();
        const_iterator cend();
        unsigned int size();
        void add(const T&amp;, const U&amp;);
        U&amp; operator[](const T&amp;);
    };

    template &lt;typename T, typename U&gt;
    hash_map&lt;T,U&gt;::hash_map(unsigned int _size):
        hash_entries(new hash_entry[_size]),
        filled_positions(new unsigned int[_size]()),
        hash_map_size(_size),
        num_entries(0){
    }

    template &lt;typename T, typename U&gt;
    hash_map&lt;T,U&gt;::~hash_map(){
        delete[] filled_positions;
        delete[] hash_entries;
    }

    template &lt;typename T, typename U&gt;
    typename hash_map&lt;T,U&gt;::const_iterator hash_map&lt;T,U&gt;::cbegin(){
        return hash_entries;
    }

    template &lt;typename T, typename U&gt;
    typename hash_map&lt;T,U&gt;::const_iterator hash_map&lt;T,U&gt;::cend(){
        return hash_entries+hash_map_size;
    }

    template &lt;typename T, typename U&gt;
    typename hash_map&lt;T,U&gt;::iterator hash_map&lt;T,U&gt;::begin(){
        return hash_entries;
    }

    template &lt;typename T, typename U&gt;
    typename hash_map&lt;T,U&gt;::iterator hash_map&lt;T,U&gt;::end(){
        return hash_entries+hash_map_size;
    }

    template &lt;typename T, typename U&gt;
    unsigned int hash_map&lt;T,U&gt;::size(){
        return hash_map_size;
    }

    template &lt;typename T, typename U&gt;
    void hash_map&lt;T,U&gt;::add(const T&amp; _key, const U&amp; _value){
        if (num_entries &gt;= hash_map_size){
            throw std::out_of_range("std::out_of_range : hash_map full");
        }
        unsigned int position = details::generate_hash(_key,hash_map_size);
        while (filled_positions[position]){
            position = (position+1)%hash_map_size;
        }
        filled_positions[position] = 1;
        hash_entries[position] = hash_entry(_key,_value);
        num_entries += 1;
    }

    template &lt;typename T, typename U&gt;
    U&amp; hash_map&lt;T,U&gt;::operator[](const T&amp; _key){
        unsigned int position = details::generate_hash(_key,hash_map_size);
        unsigned int count = 0;
        while (hash_entries[position].key != _key){
            if (count &gt; hash_map_size){
                throw std::invalid_argument("std::invalid_argument : key not in hash_map");
            }
            position = (position+1)%hash_map_size;
            count += 1;
        }
        return hash_entries[position].value;
    }

}

#endif // _LIB_HASHMAP
Although the description claims that most C++ types are supported, I see only int and two kinds of string.  The std::hash class is specialized for quite a few more types than that:

template&lt;&gt; struct hash&lt;bool&gt;;
template&lt;&gt; struct hash&lt;char&gt;;
template&lt;&gt; struct hash&lt;signed char&gt;;
template&lt;&gt; struct hash&lt;unsigned char&gt;;
template&lt;&gt; struct hash&lt;char16_t&gt;;
template&lt;&gt; struct hash&lt;char32_t&gt;;
template&lt;&gt; struct hash&lt;wchar_t&gt;;
template&lt;&gt; struct hash&lt;short&gt;;
template&lt;&gt; struct hash&lt;unsigned short&gt;;
template&lt;&gt; struct hash&lt;int&gt;;
template&lt;&gt; struct hash&lt;unsigned int&gt;;
template&lt;&gt; struct hash&lt;long&gt;;
template&lt;&gt; struct hash&lt;long long&gt;;
template&lt;&gt; struct hash&lt;unsigned long&gt;;
template&lt;&gt; struct hash&lt;unsigned long long&gt;;
template&lt;&gt; struct hash&lt;float&gt;;
template&lt;&gt; struct hash&lt;double&gt;;
template&lt;&gt; struct hash&lt;long double&gt;;
template&lt; class T &gt; struct hash&lt;T*&gt;;


In addition, the std::string hash is very collision-prone, as it uses only the length of the string (and the char* version doesn't even use std::strlen() - are you intending to even reinvent that wheel?).



std::size_t is missing its necessary include (usually &lt;cstdlib&gt;) and is consistently misspelt.

We need to include &lt;stdexcept&gt; for std::out_of_range and std::invalid_argument.



The compiler-generated copy constructor won't do what we want with hash_entries or filled_positions - that's dangerous, and will lead to multiple objects believing they own the pointers, and double deletion.



cbegin() and cend() functions ought to be usable on a const hash_map (and begin() and end() ought to be overloaded suitably, too).  Other const methods are lacking (such as find()) which make const maps much less useful than they ought to be.