std::hash
| ヘッダ <bitset>
|
||
| で定義 <coroutine>
|
||
| ヘッダ <chrono>
|
で定義 (C++26以上) |
|
| ヘッダ <filesystem>
|
||
| で定義 <functional>
|
||
| ヘッダ <memory>
|
||
| で定義 <optional>
|
||
| ヘッダ <stacktrace>
|
||
| で定義 <string>
|
||
| ヘッダ <string_view>
|
||
| ヘッダ <text_encoding>
|
||
| で定義 <thread>
|
||
| ヘッダ <typeindex>
|
||
| で定義 <variant>
|
||
| ヘッダ <vector>
|
||
template< class Key >
struct hash;
|
で定義 (C++11以上) | |
無順序連想コンテナ std::unordered_set, std::unordered_multiset, std::unordered_map, std::unordered_multimap は、テンプレート std::hash の特殊化をデフォルトのハッシュ関数として使用します。
型 Key が与えられたとき、各特殊化 std::hash<Key> は有効(enabled) または 無効(disabled) のいずれかです:
- もし
std::hash<Key>がプログラムまたはユーザーによって提供されていない場合、それは無効です。 - そうでなければ、
std::hash<Key>は以下の条件がすべて満たされる場合に有効となります:
- 以下の要件がすべて満たされる:
- Hash (関数呼び出しの引数型として
Keyを使用) - DefaultConstructible
- CopyAssignable
- Swappable
- Hash (関数呼び出しの引数型として
- 以下の値が与えられたとき:
h、型std::hash<Key>のオブジェクト。k1とk2、型Keyのオブジェクト。
- 以下の要件がすべて満たされる:
- もし
k1 == k2がtrueならば、h(k1) == h(k2)もまたtrueである。 std::hash<Key>が プログラム定義の特殊化 でない限り、h(k1)は例外を送出しません。
- もし
- そうでなければ、
std::hash<Key>は無効です。
無効な特殊化は Hash を満たさず、FunctionObject を満たさず、以下の値はすべて false です:
std::is_default_constructible<std::hash<Key>>::valuestd::is_copy_constructible<std::hash<Key>>::valuestd::is_move_constructible<std::hash<Key>>::valuestd::is_copy_assignable<std::hash<Key>>::valuestd::is_move_assignable<std::hash<Key>>::value
言い換えれば、それらは存在しますが、使用することはできません。
ネスト型
|
(C++20まで) |
メンバー関数
|
ハッシュ関数オブジェクトを構築する
(public member function) |
|
|
引数のハッシュ値を計算する
(public member function) |
標準ライブラリ特殊化
std::hashテンプレートを宣言する各ヘッダーは、
以下の型に対して有効化されたstd::hashの特殊化も提供します:
- all cv-unqualified 算術型
- all cv-unqualified 列挙型
- all cv-unqualified ポインタ型
- std::nullptr_t
|
フリースタンディング実装 は、前述の特殊化とデフォルトで無効化されている特殊化を提供することが要求される。 |
(C++20以降) |
さらに、一部のヘッダーはライブラリ型に対するその他の有効な
std::hash
特殊化も提供しています(
下記
を参照)。
|
標準ライブラリが提供する全ての
|
(C++17以降) |
ライブラリ型に対する特殊化
言語サポートライブラリ |
|
|
std::coroutine_handle
のハッシュサポート
(クラステンプレートの特殊化) |
|
診断ライブラリ |
|
|
(C++11)
|
std::error_code
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++17)
|
std::error_condition
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++11)
|
std::type_index
のハッシュサポート
(クラステンプレートの特殊化) |
|
std::stacktrace_entry
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::basic_stacktrace
のハッシュサポート
(クラステンプレートの特殊化) |
|
メモリ管理ライブラリ |
|
|
(C++11)
|
std::unique_ptr
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++11)
|
std::shared_ptr
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++26)
|
std::indirect
のハッシュサポート
(クラステンプレートの特殊化) |
汎用ユーティリティライブラリ |
|
|
(C++17)
|
std::optional
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++17)
|
std::variant
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++17)
|
std::monostateのハッシュサポート
std::monostate
(クラステンプレートの特殊化) |
|
(C++11)
|
std::bitset
のハッシュサポート
(クラステンプレートの特殊化) |
コンテナライブラリ |
|
|
(C++11)
|
std::vector<bool>のハッシュサポート
std::vector<bool>
(クラステンプレートの特殊化) |
文字列ライブラリ |
|
|
(C++11)
|
文字列のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++17)
(C++17)
(C++20)
(C++17)
(C++17)
|
文字列ビューのハッシュサポート
(クラステンプレートの特殊化) |
テキスト処理ライブラリ |
|
|
(C++26)
|
std::text_encoding
のハッシュサポート
(クラステンプレートの特殊化) |
時間ライブラリ |
|
|
std::chrono::duration
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::time_point
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
(C++26)
|
std::chrono::day
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++26)
|
std::chrono::month
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++26)
|
std::chrono::year
のハッシュサポート
(クラステンプレートの特殊化) |
|
(C++26)
|
std::chrono::weekdayのハッシュサポート
std::chrono::weekday
(クラステンプレートの特殊化) |
|
std::chrono::weekday_indexed
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::weekday_last
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::month_day
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::month_day_lastのハッシュサポート
std::chrono::month_day_last
(クラステンプレートの特殊化) |
|
|
std::chrono::month_weekday
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::month_weekday_last
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::year_month
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::year_month_dayのハッシュサポート
std::chrono::year_month_day
(クラステンプレートの特殊化) |
|
|
std::chrono::year_month_day_last のハッシュサポート
std::chrono::year_month_day_last
(クラステンプレートの特殊化) |
|
|
std::chrono::year_month_weekday
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::year_month_weekday_last
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::zoned_time
のハッシュサポート
(クラステンプレートの特殊化) |
|
|
std::chrono::leap_second
のハッシュサポート
(クラステンプレートの特殊化) |
|
入出力ライブラリ |
|
|
std::filesystem::path
のハッシュサポート
(クラステンプレートの特殊化) |
|
並行性サポートライブラリ |
|
|
(C++11)
|
std::thread::id
のハッシュサポート
(クラステンプレートの特殊化) |
注記
実際のハッシュ関数は実装依存であり、上記で指定された基準以外の品質要件を満たす必要はありません。特に、整数をそれ自身にマッピングする自明な(恒等)ハッシュ関数を使用する実装もあります。言い換えれば、これらのハッシュ関数は例えば暗号学的ハッシュとしてではなく、非順序連想コンテナで動作するように設計されています。
ハッシュ関数は、プログラムの単一の実行内で同じ入力に対して同じ結果を生成することが求められるのみです。これにより、衝突サービス拒否攻撃を防ぐソルト付きハッシュが可能となります。
C文字列に対する特殊化は存在しません。 std :: hash < const char * > はポインタの値(メモリアドレス)のハッシュを生成し、文字配列の内容を検査しません。
std::pair
および標準コンテナ型の追加特殊化、ならびにハッシュを合成するためのユーティリティ関数は、
boost::hash
で利用可能です。
例
#include <cstddef> #include <functional> #include <iomanip> #include <iostream> #include <string> #include <unordered_set> struct S { std::string first_name; std::string last_name; bool operator==(const S&) const = default; // C++20以降 }; // C++20以前 // bool operator==(const S& lhs, const S& rhs) // { // return lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name; // } // カスタムハッシュは独立した関数オブジェクトとして定義可能 struct MyHash { std::size_t operator()(const S& s) const noexcept { std::size_t h1 = std::hash<std::string>{}(s.first_name); std::size_t h2 = std::hash<std::string>{}(s.last_name); return h1 ^ (h2 << 1); // または boost::hash_combine を使用 } }; // std::hashのカスタム特殊化はstd名前空間に注入可能 template<> struct std::hash<S> { std::size_t operator()(const S& s) const noexcept { std::size_t h1 = std::hash<std::string>{}(s.first_name); std::size_t h2 = std::hash<std::string>{}(s.last_name); return h1 ^ (h2 << 1); // または boost::hash_combine を使用 } }; int main() { std::string str = "Meet the new boss..."; std::size_t str_hash = std::hash<std::string>{}(str); std::cout << "hash(" << std::quoted(str) << ") =\t" << str_hash << '\n'; S obj = {"Hubert", "Farnsworth"}; // 独立した関数オブジェクトの使用 std::cout << "hash(" << std::quoted(obj.first_name) << ", " << std::quoted(obj.last_name) << ") =\t" << MyHash{}(obj) << " (MyHash使用) または\n\t\t\t\t" << std::hash<S>{}(obj) << " (注入された特殊化を使用)\n"; // カスタムハッシュによりカスタム型を非順序コンテナで使用可能 // この例では上記で注入されたstd::hash<S>特殊化を使用 // MyHashを使用する場合は、第2テンプレート引数として渡す std::unordered_set<S> names = {obj, {"Bender", "Rodriguez"}, {"Turanga", "Leela"}}; for (auto const& s: names) std::cout << std::quoted(s.first_name) << ' ' << std::quoted(s.last_name) << '\n'; }
出力例:
hash("Meet the new boss...") = 10656026664466977650
hash("Hubert", "Farnsworth") = 12922914235676820612 (using MyHash) または
12922914235676820612 (using injected specialization)
"Bender" "Rodriguez"
"Turanga" "Leela"
"Hubert" "Farnsworth"
欠陥報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2119 | C++11 | 拡張整数型の特殊化が欠如していた | 提供された |
| LWG 2148 | C++11 | 列挙型の特殊化が欠如していた | 提供された |
| LWG 2543 | C++11 |
std::hash
SFINAEフレンドリーではない可能性があった
|
SFINAEフレンドリーに変更された |
| LWG 2817 | C++11 | std::nullptr_t の特殊化が欠如していた | 提供された |