Strange MSVC behaviour with std::experimental::is_detected

后端 未结 2 2031
囚心锁ツ
囚心锁ツ 2021-01-14 23:02

I implemented std::experimental::is_detected based on this article on cppreference.com (Part of the code is below + working repro).

It works well on G++

相关标签:
2条回答
  • 2021-01-14 23:37

    Here's a workaround that appears to work with recent MSVC (tested with Visual C++ 19.00.23720.0):

    #include <type_traits>
    
    template <typename...>
    using void_t = void;
    
    namespace internal
    {
        template <typename V, typename D>
        struct detect_impl
        {
            using value_t = V;
            using type = D;
        };
    
        template <typename D, template <typename...> class Check, typename... Args>
        auto detect_check(char)
            -> detect_impl<std::false_type, D>;
    
        template <typename D, template <typename...> class Check, typename... Args>
        auto detect_check(int)
            -> decltype(void_t<Check<Args...>>(),
                        detect_impl<std::true_type, Check<Args...>>{});
    
        template <typename D, typename Void, template <typename...> class Check, typename... Args>
        struct detect : decltype(detect_check<D, Check, Args...>(0)) {};
    }
    
    struct nonesuch
    {
        nonesuch() = delete;
        ~nonesuch() = delete;
        nonesuch(nonesuch const&) = delete;
        void operator=(nonesuch const&) = delete;
    };
    
    template <template< typename... > class Check, typename... Args>
    using is_detected = typename internal::detect<nonesuch, void, Check, Args...>::value_t;
    

    (The dummy void parameter is unused now, it's there just to keep the rest of the implementation intact.)

    0 讨论(0)
  • 2021-01-14 23:49

    You need a C++11 compiler to compile the above code, and MSVC 2015 is not a C++11 compiler.

    The particular deficit in C++11 compliance you are running into is called "expression SFINAE" by microsoft. Keep an eye out for it being fixed.

    Basically, decltype cannot be used for SFINAE. In laymans terms, SFINAE is the technique you are using for selecting overloads of template functions or classes.

    There is usually no workaround.

    0 讨论(0)
提交回复
热议问题