標準ライブラリの順序付けられていないコンテナのデフォルトのインスタンス化を使用して、特定の型がハッシュ可能かどうか、したがってstd::hash. これは非常に便利な機能だと思います (たとえば、一般的なコードでstd::setフェールセーフとして使用する場合など)。std::unordered_setそこで私は、std::hashタイプごとに定義されていないと考えて、次の SFINAE ソリューションを作成し始めました。
template<typename T> std::true_type hashable_helper(
const T&, const typename std::hash<T>::argument_type* = nullptr);
template<typename T> std::false_type hashable_helper(...);
//It won't let me derive from decltype directly, why?
template<typename T> struct is_hashable
: std::is_same<decltype(hashable_helper<T>(std::declval<T>())),
std::true_type> {};
(これが最善の解決策でない場合、または間違っている場合でも、私のささやかな SFINAE 能力を許してください。)
しかし、その後、gcc 4.7とVC++ 2012の両方が、特殊化されていないバージョンで ing するだけでstd::hash、任意の typeを定義することを学びました。しかし、条件付きでコンパイルする代わりに (さらにgcc 4.7のlibstdc++を使用して3.1 をclangします)、アサーションに失敗し、コンパイル エラーが発生します。s は SFINAE によって処理されないと思うので (そうですか?)、これは合理的に思えます。一般的なテンプレートにさえないのに、そのテンプレートを定義していないのはさらに悪いことですTstatic_assertstatic_assertgcc 4.6static_assertstd::hash()これを使用しようとするとリンカー エラーが発生します (これは常にコンパイル エラーよりも悪く、リンカー エラーをコンパイラ エラーに変換する方法は想像できません)。
std::hashしたがって、型に有効な特殊化がある場合、または少なくともライブラリstatic_assertが一般的なテンプレートで ing (何らかの方法でstatic_assertエラーを SFINAE 非エラーに変換する)の場合に返すような型特性を定義する、標準に準拠した移植可能な方法はありますか?