3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++のstd::unordered_mapのキーにstd::pairを使いたい

Last updated at Posted at 2022-04-24

はじめに

Qiitaにいくつか同じ内容の記事があるのは知っていますが, 満足できる内容ではなかったため書きました.

実装

ハッシュ値の結合はこちらを参考にしました(PDF注意).

#include <cstdint>
#include <unordered_map>
#include <functional>
#include <algorithm>
#include <string>
#include <iostream>

template<class T>
T hash_combine(T h0, T h1)
{}

template<>
uint32_t hash_combine<uint32_t>(uint32_t h0, uint32_t h1)
{
    return h1 ^ (h0 + 0x9E3779B9U + (h1<<6) + (h1>>2));
}

template<>
uint64_t hash_combine<uint64_t>(uint64_t h0, uint64_t h1)
{
    return h1 ^ (h0 + 0x9E3779B97F4A7C15ULL + (h1<<12) + (h1>>4));
}

struct pair_hash
{
    using key_type = std::pair<uint32_t, std::string>;
    using first_type = key_type::first_type;
    using second_type = key_type::second_type;

    size_t operator()(const key_type& key) const
    {
        size_t h0 = std::hash<first_type>{}(key.first);
        size_t h1 = std::hash<second_type>{}(key.second);
        return hash_combine(h0, h1);
    }
};

int main(void)
{
    using map_type = std::unordered_map<std::pair<uint32_t, std::string>, uint32_t, pair_hash>;
    map_type map = {
        {{0, "0"}, 0},
        {{0, "1"}, 1},
        {{1, "0"}, 2},
        {{1, "1"}, 3},
    };
    for_each(map.begin(), map.end(), [](const map_type::value_type& x){ std::cout << "(" << x.first.first << "," << x.first.second << ")=>" << x.second << std::endl;});
    return 0;
}

まとめ

std::to_stringで文字列にしてしまうと, 速度の問題以前にロケールの影響を受けます. 実用上ほとんどの場合問題になることはないとはいえ, 問題になるケースを踏んでしまうと発見が困難と予想されるため, 日曜プログラミング以外では使わない方がいいでしょう.

3
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?