I have a function that needs to enumerate an iterator multiple times, but according to MSDN, "Once you increment any copy of an input iterator, none of the other copies can safely be compared, dereferenced, or incremented thereafter."
So to make things easier, instead of creating a separate implementation for non-forward-iterators that copies the data and enumerates the copy, I want to restrict my method to only taking in forward iterators, and rejecting input iterators statically.
Right now I have something like:
template<typename It, typename TCallback /*signature: bool(value_type)*/>
bool EnumerateTwice(const It &begin, const It &end, TCallback callback)
{
for (It it = begin; it != end; ++it)
if (!callback(*it))
return false;
for (It it = begin; it != end; ++it)
if (!callback(*it))
return false;
return true;
}
but nothing restricts It
to being a forward iterator.
How do I place that restriction on the templated function? (C++03)
You can use SFINAE and replace bool
by:
typename enable_if<
is_same<typename std::iterator_traits<It>::iterator_category,
std::forward_iterator_tag>::value,
bool>::type
You may need to define is_same
and enable_if
yourself if you don't want to pull them from Boost or TR1:
template <typename A, typename B>
struct is_same { static const bool value = false; };
template <typename T>
struct is_same<T, T> { static const bool value = true; };
template <bool, typename> struct enable_if { };
template <typename T> struct enable_if<true, T> { typedef T type; };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With