------- 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