2

I'm implementing an open address hash table like this:

template <typename  K, typename V> 
class open_addressing_map
{
public:
    using key_type = K;
    using mapped_type = V;
    using value_type = std::pair<const key_type, mapped_type>;
    using hasher = std::hash<K>;
    using hash_code = std::size_t;
    using allocator_type = std::allocator<value_type>;

    value_type* buckets; //array of value, allocate at constructor
    std::size_t capacity; //capacity buckets
    hasher hash_func;
    allocator_type allocator;

private:
    std::pair<std::size_t, bool> find_internal(hash_code hash, const key_type& key);
    std::size_t find_free_bucket(hash_code hash);

public:
    template<typename ...Args>
    std::pair<iterator, bool> emplace(Args&& ...args) {
        //I need to construct a key_type in stack here to pass into find() and find_free_bucket
        //I don't want to construct a value_type because it can be expensive.
        key_type key = ...?; //how can I do this

        hash_code hash;
        hash = hash_func(key); 

        auto res = find(hash, key);
        //if not found
        if (!res.second) {
            std::size_t free_idx = find_free_bucket(hash);
            if (hash == capacity)
                return {iterator(capacity), false};
            else {
                //need to rehash then insert a gain.
            }
            //construct value
            allocator.construct(std::forward<Args&&>(args)...);
        }
    }

};

The problem is I use an with capacity which was pre-allocated at constructor to reduce allocation overhead. In emplace function, I need to find correct position to construct the value, but need the key before I can get this position.

I can construct a value_type here to get the key but later, I have to move it to correct position in buckets array.

The idea is construct only the key in stack, but I don't know how to do this?

Phạm Văn Thông
  • 743
  • 2
  • 7
  • 21
  • 1
    As I understand your question, you expect to pass a key as a first argument to `emplace()`. If so, then: `template std::pair emplace(Key &&key, Args&& ...args)`. There's your key. Have fun. – Sam Varshavchik Jul 17 '17 at 03:05
  • Args... is arguments which will be passed into pair constructor, it can be a pair, or two tuple, or whatever can be passed into `value_type`'s constructor – Phạm Văn Thông Jul 17 '17 at 03:37
  • That's not typically how `emplace()` is used. `emplace()` receives the arguments to the type being constructed, and not an object that can be converted to the type being constructed. In this case, the first argument to your pair's constructor is the key type, therefore the first argument to `emplace()` will always be `key_type`. – Sam Varshavchik Jul 17 '17 at 03:40

0 Answers0