Это возможно, перемещая ошибку специализации из списка аргументов шаблона, так что вывод параметра E все еще может происходить. Например, это может произойти в объявлении using:
namespace std {
template<class E>class hash {
using sfinae = typename std::enable_if<std::is_enum<E>::value, E>::type;
public:
size_t operator()(const E&e) const {
return std::hash<typename std::underlying_type<E>::type>()(e);
}
};
};
(я обычно использую имя типа sfinae
, чтобы я помню, почему он там есть.)
Демо-код:
#include <functional>
namespace std {
template<class E>class hash {
using sfinae = typename std::enable_if<std::is_enum<E>::value, E>::type;
public:
size_t operator()(const E&e) const {
return std::hash<typename std::underlying_type<E>::type>()(e);
}
};
};
enum foo { BAR, BAZ };
class quux {};
int main() {
// Compiles.
std::hash<foo>foo_hash;
// Gives a compile-time error: no type named ‘type’ in ‘struct
// std::enable_if<false, quux>’.
std::hash<quux>quux_hash;
return 0;
}