Verifique se o tipo é hashble
Eu gostaria de fazer um traço de tipo para verificar se um tipo específico é hashable usando as instanciações padrão dos contêineres não-ordenados da biblioteca padrão, portanto, se ele tem uma especialização válida parastd::hash
. Acho que isso seria um recurso muito útil (por exemplo, para usarstd::set
como à prova de falhas parastd::unordered_set
em código genérico). Então eu, pensandostd::hash
não está definido para cada tipo, começou a fazer a seguinte solução 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> {};
(Perdoe minhas habilidades modestas de SFINAE se esta não for a melhor solução ou até mesmo errada.)
Mas então eu aprendi que ambosgcc 4.7 eVC ++ 2012 definirstd::hash
para qualquer tipoT
, somentestatic_assert
na versão não especializada. Mas em vez de compilar condicionalmente eles (e tambémclangor 3.1 usandogcc 4.7'slibstdc ++) falha a declaração resultando em um erro de compilação. Isso parece razoável, já que eu achostatic_assert
s não são tratados pela SFINAE (certo?), então uma solução da SFINAE parece não ser de forma alguma. É ainda pior paragcc 4.6
que nem sequer tem umstatic_assert
no geralstd::hash
modelo, mas apenasnão define Está()
operador, resultando em um erro de vinculador ao tentar usá-lo (que é sempre pior que um erro de compilação e não consigo imaginar nenhuma maneira de transformar um erro de vinculador em um erro do compilador).
Então, existe alguma maneira padrão e portátil de definir tal característica de tipo retornando se um tipo tem um valor válido?std::hash
especialização, ou talvez pelo menos para as bibliotecasstatic_assert
no modelo geral (de alguma forma, transformando ostatic_assert
erro em um erro não SFINAE)?