Проверьте, является ли тип хэшируемым
Я хотел бы сделать признак типа для проверки, является ли конкретный тип хешируемым, используя экземпляры по умолчанию для неупорядоченных контейнеров стандартной библиотеки, таким образом, если он имеет действительную специализацию для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 определятьstd::hash
для любого типаT
, простоstatic_assert
в неспециализированной версии. Но вместо условной компиляции они (а такжеclang 3.1 с помощьюgcc 4.7& APOS; slibstdc++) не соответствует утверждению, что приводит к ошибке компиляции. Это кажется разумным, так как я думаю,static_assert
SFINAE не обрабатывает их (верно?), поэтому решение SFINAE, по-видимому, вообще невозможно. Это еще хуже дляgcc 4.6
который даже не имеетstatic_assert
в общемstd::hash
шаблон но простоdoesn't define его()
оператор, приводящий к ошибке компоновщика при попытке его использовать (что всегда хуже, чем ошибка компиляции, и я не могу представить какой-либо способ превратить ошибку компоновщика в ошибку компилятора).
Таким образом, существует ли какой-либо стандартный и переносимый способ определения такой черты типа, возвращаемой, если тип имеет действительныйstd::hash
специализация или, может быть, хотя бы для библиотекstatic_assert
в общем шаблоне (каким-то образомstatic_assert
ошибка в SFINAE не ошибка)?