SlideShare a Scribd company logo
1 of 9
Download to read offline
C++14 LWG.2148
列挙型のハッシュサポート
高橋 晶(Akira Takahashi)
faithandbrave@longgate.co.jp
2014/06/27(金) WG21 C++14 DISレビュー会議
まえがき
• この資料は、C++14に取り入れられる予定の変更、LWG
(Library Working Group)のIssue 2148のレビューです。
• 2148. Hashing enums should be supported directly by
std::hash
• http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-
defects.html#2148
概要
• std::unordered_mapのキーとして列挙型を指定可能にする。
• そのために、enumおよびenum classで定義されたあらゆる列
挙型(列挙型コンセプトを満たすあらゆる型)を、std::hash
クラスがサポートする。
規格の変更内容 1/2
• 20.9 [function.objects], <functional>のヘッダ概要
namespace std {
[…]
// 20.8.12, hash function baseprimary template:
template <class T> struct hash;
[…]
}
規格の変更内容 2/2
• 20.8.12 [unord.hash] のパラグラフ1
-1- The unordered associative containers defined in 23.5
[unord] use specializations of the class template hash as
the default hash function. For all object types Key for which
there exists a specialization hash<Key>, and for all
enumeration types (7.2 [dcl.enum]) Key, the instantiation
hash<Key> shall: […]
非順序連想コンテナは、デフォルトのハッシュ関数としてクラステンプレート
hashの特殊化を使用する。hash<Key>の特殊化が存在するKey型の全てのオブジェ
クト、および全ての列挙型Keyについて、hash<Key>のインスタンス化は以下を満
たさなければならない:
どのように実装するか 1/2
• libc++は、以下のように実装している:
namespace std {
template <class T> // プライマリテンプレート
struct hash {
static_assert(is_enum<T>::value, “…”);
!
size_t operator()(T x) const noexcept
{
using type = typename underlying_type<T>::type;
return hash<type>{}(static_cast<type>(x));
}
};
}
どのように実装するか 2/2
• std::hashのプライマリテンプレートを、enum用に使う。
• std::underlying_typeメタ関数を使用して、列挙型のベース
となる整数型を取得し、
• 整数型のstd::hash特殊化に転送する。
所感
• 今後、このようなコンセプトによる特殊化が標準ライブラリ
内でさらに必要になった場合、std::hashのプライマリテン
プレートが複雑になっていく。
• 具体的には、コンセプトごとにハッシュ関数を切り替えるために、実装用
の関数テンプレートを用意し、SFINAEもしくはConceptでオーバーロー
ドしていくことになる。
• そのような提案が上がってきた場合には、std::hashクラス
テンプレートの仕様を整理する必要がある。
• Boostのように、オーバーロード可能な関数を実装として

許可することが考えられる。
考えられる仕様
namespace std {
template <Enumerable T>
size_t hash_value(T x) noexcept;
!
template <class T> // プライマリテンプレート
struct hash {
size_t operator()(T x) const noexcept
{
return hash_value(x); // 関数テンプレートに転送
}
};
}
• ADLについても考える必要がある。

More Related Content

More from Akira Takahashi (20)

Cpp20 overview language features
Cpp20 overview language featuresCpp20 overview language features
Cpp20 overview language features
 
Cppmix 02
Cppmix 02Cppmix 02
Cppmix 02
 
Cppmix 01
Cppmix 01Cppmix 01
Cppmix 01
 
Modern C++ Learning
Modern C++ LearningModern C++ Learning
Modern C++ Learning
 
cpprefjp documentation
cpprefjp documentationcpprefjp documentation
cpprefjp documentation
 
C++1z draft
C++1z draftC++1z draft
C++1z draft
 
Boost tour 1_61_0 merge
Boost tour 1_61_0 mergeBoost tour 1_61_0 merge
Boost tour 1_61_0 merge
 
Boost tour 1_61_0
Boost tour 1_61_0Boost tour 1_61_0
Boost tour 1_61_0
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
 
Boost tour 1.60.0 merge
Boost tour 1.60.0 mergeBoost tour 1.60.0 merge
Boost tour 1.60.0 merge
 
Boost tour 1.60.0
Boost tour 1.60.0Boost tour 1.60.0
Boost tour 1.60.0
 
Boost container feature
Boost container featureBoost container feature
Boost container feature
 
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 mergeBoost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
 
Boost Tour 1_58_0
Boost Tour 1_58_0Boost Tour 1_58_0
Boost Tour 1_58_0
 
Multi paradigm design
Multi paradigm designMulti paradigm design
Multi paradigm design
 
Start Concurrent
Start ConcurrentStart Concurrent
Start Concurrent
 
Programmer mind
Programmer mindProgrammer mind
Programmer mind
 
Boost.Study 14 Opening
Boost.Study 14 OpeningBoost.Study 14 Opening
Boost.Study 14 Opening
 
Executors and schedulers
Executors and schedulersExecutors and schedulers
Executors and schedulers
 
Improvement future api
Improvement future apiImprovement future api
Improvement future api
 

C++14 enum hash