
Howard Hinnant wrote:
Fwiw, I used something closely related in libc++ for SFINAE on the “member template members” of the containers (the ones taking iterators) to disambiguate them from the members/constructors not taking iterators, but having the same number of parameters. But instead of is_iterator, I needed is_input_iterator, is_forward_iterator, etc.
That was exactly what I had in mind. Instead of enable_if on is_iterator<T>, it's almost always better to use enable_if on is_convertible<typename iterator_traits<T>::iterator_category, tag>, where tag is the kind of iterator the function actually needs. (This requires the new and improved iterator_traits though - were those C++14?) About the only use case I can envisage for the plain is_iterator is template<class It> typename enable_if<is_iterator<T>::value>::type function( It first, It last ) { static_assert( is_forward_iterator<T>::value, "'function' requires forward iterators" ); // ... } where you deliberately don't SFINAE out the function in order to produce a better error message in the presence of other overloads. But even then... is_input_iterator would be good enough, I suppose. (-pedantic on: an iterator is not required to have nested types, so the implementation is not quite correct. Of course, again, without the new and improved iterator_traits, it's the best that we can do.)