How to SFINAE out non-containers parameters

后端 未结 1 500
夕颜
夕颜 2021-01-12 15:38

I have a template function that I want to enable only for standard containers (or containers compatible with standard containers, which at least provide a begin()

相关标签:
1条回答
  • 2021-01-12 15:55

    Using void_t, we can just make a type trait for having begin() and end() (and anything else you might want to check for, like typename T::iterator, you can just keep piling expressions on):

    template <typename T, typename = void>
    struct is_std_container : std::false_type { };
    
    template <typename T>
    struct is_std_container<T,
        void_t<decltype(std::declval<T&>().begin()),
               decltype(std::declval<T&>().end()),
               typename T::value_type
               >>
        : std::true_type { };
    

    And then just SFINAE on that:

    template <typename Container>
    typename std::enable_if<
        is_std_container<Container>::value,
        typename Container::value_type
    >::type 
    f(const Container& c) { .. }
    

    Also, if you really wanted to verify that begin() gives you back a T::iterator (or at least that they're equality comparable), you can do that too:

    void_t<
        decltype(begin(std::declval<T&>()) == std::declval<typename T::iterator>())
    >
    
    0 讨论(0)
提交回复
热议问题