在 Qt 中,我有一个绝妙的(咳嗽、咳嗽)想法,开始为标准库数据类型定义 qHash(用于 QHash 的散列函数,Qt 的关联容器之一)的重载: std::basic_stringstd::shared_ptr 等。

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

也就是说,我可以使用表达式 SFINAE 来实现这样的事情:

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

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

因此,问题是:有没有办法做同样的事情,以某种方式
  • 不使用表达式 SFINAE
  • 保证适用于所有 MSVC 版本 >= 2013?

  • 我在想通过 enable_if 之类的简单的 ol'C++98 SFINAE 构造,但其他 SO 答案(如 this one )让我认为 MSVC 2013 也可能会错误编译,因此结果再次变得 Not Acceptable 。

    最佳答案

    我认为您不需要为此表达 SFINAE,这些方面的东西应该可以工作。

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

    或者几乎任何在 hash::result_type 上执行 SFINAE 的方法。不幸的是,hash::result_type 在 C++17 中已被弃用,但您仍然可以为 MSVC 2013 使用 #ifdef 此代码。

    关于c++ - 我可以在所有 MSVC >= 2013 上安全地使用哪些 SFINAE 技巧?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40493479/

    10-13 07:05