Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict an iterator to being a forward iterator?

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)

like image 932
user541686 Avatar asked Jan 05 '12 23:01

user541686


1 Answers

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; };
like image 132
Kerrek SB Avatar answered Sep 27 '22 21:09

Kerrek SB