c++ - How to SFINAE out non-containers parameters -
i have template function want enable standard containers (or containers compatible standard containers, @ least provide begin() member function). i'm sfinae-ing out non-containers in following way:
template<typename container> typename container::value_type f(const container& c, typename std::enable_if< std::is_same< decltype(*c.begin()), typename container::value_type >::value >::type* = nullptr) { // implementation here } the std::is_same , decltype don't elegant. there better way of doing this?
ps: need sfinae here because have different overload
template<typename derived> f(const eigen::matrixbase<derived>& a) and whenever try f(some_eigen_matrix), container overload ends being picked up, compiler spits out error because type lacking begin().
using void_t, can make type trait having begin() , end() (and else might want check for, typename t::iterator, can 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 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 wanted verify begin() gives t::iterator (or @ least they're equality comparable), can too:
void_t< decltype(begin(std::declval<t&>()) == std::declval<typename t::iterator>()) >
Comments
Post a Comment