Проверьте, является ли тип хэшируемым
Я хотел бы сделать черту типа для проверки, является ли конкретный тип хэшируемым, используя стандартные экземпляры стандартной библиотеки 'неупорядоченные контейнеры, таким образом, если он имеет действительную специализацию дляstd::hash
, Я думаю, что это будет очень полезная функция (например, для использованияstd::set
как безопасное дляstd::unordered_set
в общем коде). Так я, думаяstd::hash
не определен для каждого типа, начал делать следующее решение SFINAE:
template std::true_type hashable_helper(
const T&, const typename std::hash::argument_type* = nullptr);
template std::false_type hashable_helper(...);
//It won't let me derive from decltype directly, why?
template struct is_hashable
: std::is_same {};
(Прости мои скромные способности SFINAE, если это не лучшее решение или даже неправильно.)
Но потом я узнал, что обаgcc 4.7 а такжеVC ++ 2012 определятьstd::hash
для любого типаT
, простоstatic_assert
в неспециализированной версии. Но вместо условной компиляции они (а такжелязг 3.1 с помощьюGCC 4,7libstdc ++) не соответствует утверждению, что приводит к ошибке компиляции. Это кажется разумным, так как я думаю,static_assert
SFINAE не обрабатывает их (верно?), поэтому решение SFINAE, по-видимому, вообще невозможно. Это'еще хуже дляgcc 4.6
который нет даже естьstatic_assert
в общемstd::hash
шаблон но простоБезразлично»т определить его()
оператор, приводящий к ошибке компоновщика при попытке его использовать (что всегда хуже, чем ошибка компиляции, и я не могу представить какой-либо способ превратить ошибку компоновщика в ошибку компилятора).
Таким образом, существует ли какой-либо стандартный и переносимый способ определения такой черты типа, возвращаемой, если тип имеет действительныйstd::hash
специализация или, может быть, хотя бы для библиотекstatic_assert
в общем шаблоне (каким-то образомstatic_assert
ошибка в SFINAE не ошибка)?