У меня есть функция хэширования, которая может принимать любой тип объекта и хеш-код, он использует внутри себя std::hash
. Поскольку std::hash
не поддерживает перечисления типов я создал перегруженные функции, 1 для перечислений с использованием std::underlying_type
и 1 для других типов:std :: условный vs std :: enable_if
template <typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
static std::size_t Hash(T const & t)
{
return std::hash<typename std::underlying_type<T>::type>()(t);
}
template <typename T, typename std::enable_if<!std::is_enum<T>::value>::type* = nullptr>
static std::size_t Hash(T const & t)
{
return std::hash<T>()(t);
}
Это работает отлично. Затем я попытался поставить все это в одну функцию с std::conditional
:
template <typename T>
static std::size_t Hash(T const & t)
{
typedef typename std::conditional<std::is_enum<T>::value, std::hash<typename std::underlying_type<T>::type>, std::hash<T>>::type Hasher;
return Hasher()(t);
}
Main:
enum test
{
TEST = 2
};
int main() {
Hash<test>(TEST);
Hash<int>(5);
std::cin.get();
return 0;
}
Это, однако, дал мне error:
/usr/include/c++/5/type_traits:2190:38: error: 'int' is not an enumeration type typedef __underlying_type(_Tp) type;
я понимаю ошибка, но я не понимаю, почему, я думал, что std::conditional
предотвратит эти ошибки во время компиляции, потому что <int>
использует std::hash<T>
вместо std::hash<typename std::underlying_type<T>::type>
во время компиляции.
Что я делаю неправильно здесь, есть способ, которым я могу объединить две функции?
Короче говоря, 'условный' требует, чтобы обе ветви были хорошо сформированы. Слияние обеих ветвей может быть выполнено с помощью структуры признаков. – Rostislav