Checking whether a function (not a method) exists in c++11 via templates

前端 未结 2 1521
猫巷女王i
猫巷女王i 2021-01-13 13:52

So with SFINAE and c++11, it is possible to implement two different template functions based on whether one of the template parameters can be substituted.

For exampl

相关标签:
2条回答
  • 2021-01-13 14:46

    I find the void_t trick to be usually preferable to the traditional SFINAE method shown in the other answer.

    template<class...> using void_t = void; // now in the C++17 working paper!
    // GCC <= 4.9 workaround:
    // template<class...> struct voider { using type = void; };
    // template<class... T> using void_t = typename voider<T...>::type;
    
    template<class, class = void>
    struct is_ostreamable : std::false_type {};
    
    template<class T>
    struct is_ostreamable<T, void_t<decltype(std::declval<std::ostream&>() <<
                                             std::declval<T>())>> : std::true_type {};
    

    The partial specialization is selected if and only if the expression is well-formed.

    Demo. Note that the & in std::declval<std::ostream&>() is important, because otherwise std::declval<std::ostream>() is an rvalue and you'll get ostream's catchall rvalue stream insertion operator, and report that everything is streamable.

    The above code checks for an operator<< that can accept a T rvalue . If you want to check for one that accepts an lvalue T, then use std::declval<T&>().

    0 讨论(0)
  • 2021-01-13 14:47

    Using SFINAE, it's possible like this:

    template <typename T>
    class has_ostream_lshift
    {
      struct no {};
    
      template <typename T2>
      static decltype(std::declval<std::ostream&>() << std::declval<T2>()) test(int);
    
      template <typename T2>
      static no test(...);
    
    public:
      enum { value = ! std::is_same<no, decltype(test<T>(0))>::value};
    };
    
    0 讨论(0)
提交回复
热议问题