我想创建一个类型特征,用于检查特定类型是否可以使用标准库的无序容器的默认实例化进行清理,因此如果它具有有效的特化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> {};
Run Code Online (Sandbox Code Playgroud)
(如果这不是最好的解决方案,甚至是错误的,请原谅我适度的SFINAE能力.)
但后来我了解到,gcc 4.7和VC++ 2012都定义std::hash了任何类型T,只是static_assert非专业版.但是有条不紊地编译它们(以及使用gcc 4.7的libstdc ++ 扼流3.1),而不是断言导致编译错误.这似乎是合理的,因为我认为SFINAE没有处理(对吧?),所以SFINAE解决方案似乎根本不可能.更糟糕的是,它甚至没有在通用模板中,但只是没有定义其运算符,导致在尝试使用它时出现链接器错误(这总是比编译错误更糟,我无法想象任何方式将链接器错误转换为编译器错误).static_assertgcc 4.6static_assertstd::hash()
那么,如果类型具有有效的特化std::hash,或者至少对于static_assert通用模板中的库(以某种方式将static_assert错误转换为SFINAE非错误),是否有任何符合标准且可移植的方式来定义返回类型特征?