我可以安全地在所有MSVC> = 2013上使用SFINAE技巧吗?

时间:2016-11-08 17:55:07

标签: c++ qt c++11 visual-c++ sfinae

在Qt中,我有一个很好的(咳嗽,咳嗽)想法来开始为标准库数据类型定义qHash(用于QHash的散列函数,Qt&#39关联容器之一)的重载:{{ 1}},std::basic_string等。

这个过程可能有一个捷径:而不是追逐"任何可以用作QHash"中的密钥的标准库类型。并为其添加std::shared_ptr重载,如果类型具有qHash专门化,我可以自动定义qHash(合理地假设我们不想做更多标准库在此过程中的作用)。

也就是说,我可以使用表达式SFINAE实现类似的东西:

std::hash

不幸的是,尽管Qt需要一个C ++ 11编译器,但表达式SFINAE 不允许在任何地方,因为MSVC并不完全支持它(在撰写本文时:所有MSVC版本,最多和包括VS15预览5.无论如何,Qt必须支持一直到2013年。)

因此,问题是:有没有办法以

的方式做同样的事情
  1. 不使用表达式SFINAE
  2. 保证适用于所有MSVC版本> = 2013?
  3. 我在想一个简单的好事。通过template<typename T> auto qHash(const T &t) -> decltype(std::hash<T>()(t)) { return std::hash<T>()(t); } 之类的C ++ 98 SFINAE构建,但其他SO答案(如this one)让我觉得MSVC 2013可能会错误编译,所以结果再次变得不可接受。

1 个答案:

答案 0 :(得分:2)

我认为你不需要为此表达SFINAE,这些内容应该有效。

template<typename T>
typename std::hash<T>::result_type qHash(const T &t) 
{ 
     return std::hash<T>()(t); 
}

或几乎任何在hash::result_type上执行SFINAE的方法。不幸的是,在{+ 1}}中不推荐使用hash::result_type,但您仍然可以#ifdef使用此代码进行MSVC 2013。