------- Comment #23 from jwakely dot gcc at gmail dot com 2009-12-17 11:55 ------- I can't see any 100% reliable way to prevent this problem, because the catch-all specialisation of iterator_traits can be instantiated with non-iterator types.
We could try tricks like this to restrict std::next to things that look like iterators: // deduction fails if _Iter doesn't meet InputIterator requirements template<typename _Iter, typename _Sfinae1 = decltype(*std::declval<_Iter&>()), typename _Sfinae2 = decltype(++std::declval<_Iter&>()), typename _Sfinae3 = decltype(std::declval<_Iter&>()++), typename _Sfinae4 = decltype(*std::declval<_Iter&>()++), typename _Sfinae5 = decltype(std::declval<_Iter&>()==std::declval<_Iter&>()) > typename iterator_traits<_Iter>::difference_type __safe_iterator_diff_type(_Iter); template<typename _InputIterator> inline _InputIterator next(_InputIterator __x, decltype(__safe_iterator_diff_type(__x)) __n = 1) { std::advance(__x, __n); return __x; } But that will still fail for types that have an iterator-like interface. Then again, I think such types would be detected as iterators even with concepts. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40497