【问题标题】:MSVC SFINAE: Substitution does not failMSVC SFINAE:替换不会失败
【发布时间】:2017-12-17 11:29:02
【问题描述】:

我正在尝试制作一种“has_member”。使用 Clang(对于 msvc)效果很好(我得到 0、1),但使用 MSVC 却不行(我得到 1、1)。

这是我的代码

template<typename T>
using void_t = void;

namespace detail {
    template<typename AlwaysVoid, template<typename...> typename Operator, typename ...Args>
    struct _is_valid : std::false_type {};


    template<template<typename...> typename Operator, typename ...Args>
    struct _is_valid<void_t<Operator<Args...>>, Operator, Args...> : std::true_type { using type = Operator<Args...>; };
}

template<template<typename ...> typename Operator, typename ...Args>
using is_valid = detail::_is_valid<void, Operator, Args...>;

template<typename T>
using _has_push_back = decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()));

template<typename T>
using has_push_back = is_valid<_has_push_back, T>;

int main() {
    std::cout << has_push_back<float>::value  << " " << has_push_back<std::vector<float>>::value << std::endl;

    getchar();
    return 0;
}

恕我直言,Operator&lt;Args...&gt;detail::_is_valid 中不会失败。但我不明白如何使它对 MSVC 有效。

我正在使用 Visual Studio 2017

【问题讨论】:

    标签: c++ sfinae


    【解决方案1】:

    你应该试试:

    template<typename T> struct make_void {
        using type = void;
    };
    
    template<typename T>
    using void_t = typename make_void<T>::type;
    

    is_detected 上的信息也可能有所帮助。

    【讨论】:

    • 这个 void_t 有效。但我不明白为什么这个实现比另一个更好(在我的简单案例中一直有效)。这个新的 void_t 更好,因为他“确保”使用“T”?
    • ::type 强制 SFINAE,并且有一个更改/缺陷以支持标准中 void_t 的简单别名。
    【解决方案2】:

    Visual Studio 在 SFINAE 上很糟糕。尽管他们声称已经改善了这种情况,但即使 Clang 和 GCC 可以很好地处理相同的代码,我编写的大多数(如果不是全部)SFINAE 代码(尽管数量不多)都无法工作甚至无法编译。

    将所有失败的代码发送给 Microsoft,这样您就有更大的机会修复它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-07
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 2019-09-19
      • 2018-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多