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