Me gustaría hacer un rasgo de tipo para verificar si un tipo particular es hashable utilizando las instancias predeterminadas de los contenedores no ordenados de la biblioteca estándar, por lo tanto, si tiene una especialización válida para std::hash
. Creo que esta sería una característica muy útil (por ejemplo, para usar std::set
como failsafe para std::unordered_set
en código genérico). Así que, no se define pensando std::hash
para cada tipo, empecé a hacer la siguiente solución SFINAE: (. Perdona mis modestos SFINAE-habilidades si esto no es la mejor solución o incluso erróneos)Compruebe si el tipo es hashable
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> {};
Pero entonces aprendí que gcc 4.7 y VC++ 2012 definen std::hash
para cualquier tipo T
, solo static_assert
ing en la versión no especializada. Pero en lugar de compilar condicionalmente ellos (y también sonido metálico 3.1 usando gcc 4.7 's libstdC++) fallan la afirmación que resulta en un error de compilación. Esto parece razonable ya que creo que static_assert
s no son manejados por SFINAE (¿verdad?), Por lo que una solución SFINAE parece no ser posible. Es aún peor para gcc 4.6
que ni siquiera tiene static_assert
en la plantilla general std::hash
pero no define como su operador , lo que provoca un error del enlazador al intentar usarlo (que siempre es peor que un error de compilación y No puedo imaginar ninguna forma de transformar un error de enlazador en un error de compilación).
Entonces, ¿hay alguna manera que cumplan el estándar y portátil para definir un rasgo de este tipo regresar si un tipo tiene un std::hash
especialización válida, o tal vez por lo menos para las bibliotecas static_assert
ING en la plantilla general (de alguna manera transformar el error static_assert
en un SFINAE sin errores)?
EDIT: Ok, mi declaración acerca * VC++ * compilando que era de alguna distinta versión más antigua, de hecho * VC++ * se comporta como * gcc *, asfixia en el 'static_assert' –
se parece a la gente del CCG son conscientes del problema mientras tanto. Se dice que Gcc 4.8 ya no tiene esta afirmación estática, pero que consideran implementar una implementación estándar en el futuro, algo similar al hash de Boost, donde la implementación es mejorada por ADL. – Ichthyo
https://gcc.gnu.org/ml/libstdc++/2013-03/msg00029.html – Ichthyo