標準ライブラリの順序付けられていないコンテナのデフォルトのインスタンス化を使用して、特定の型がハッシュ可能かどうか、したがって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 によって処理されないと思うので (そうですか?)、これは合理的に思えます。一般的なテンプレートにさえないのに、そのテンプレートを定義していないのはさらに悪いことですT
static_assert
static_assert
gcc 4.6
static_assert
std::hash
()
これを使用しようとするとリンカー エラーが発生します (これは常にコンパイル エラーよりも悪く、リンカー エラーをコンパイラ エラーに変換する方法は想像できません)。
std::hash
したがって、型に有効な特殊化がある場合、または少なくともライブラリstatic_assert
が一般的なテンプレートで ing (何らかの方法でstatic_assert
エラーを SFINAE 非エラーに変換する)の場合に返すような型特性を定義する、標準に準拠した移植可能な方法はありますか?