How to SFINAE out non-containers parameters

妖精的绣舞 提交于 2019-12-01 05:19:15

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>())
>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!