By definition, the std :: equal algorithm accepts only one "last" iterator. Many posts on stackoverflow indicate that in order to perform equivalence between two ranges, you must first verify that the ranges are the same size in addition to calling std :: equal. If random access iterators are available, this does not add any significant overhead. However, it seems that without random access iterators, the first code fragment, implemented only with existing STL algorithms, will be slower than the second code fragment, which is a user-defined “equivalent” algorithm (which is not part of the STL). My question is, is fragment 2 more efficient than any algorithm encoded using existing STL algorithms only? If yes,then why is this algorithm not part of the STL?
Fragment 1:
template <typename IITR1, typename IITR2>
bool equivalent(IITR1 first1, IITR1 last1, IITR2 first2, IITR2 last2)
{
return distance(first1, last1) == distance(first2, last2) &&
equal( first1, last1, first2 );
}
Fragment 2:
template <typename IITR1, typename IITR2>
bool equivalent(IITR1 first1, IITR1 last1, IITR2 first2, IITR2 last2)
{
while ( first1 != last1 && first2 != last2 ) {
if (!(*first1 == *first2)) return false;
++first1; ++first2;
}
return first1 == last1 && first2 == last2;
}
Note. I did not test it, but I would very much doubt that the compiler would optimize fragment 1 so that it would generate code with the same performance as fragment 2.
To be complete, the following code snippet is close to useless, as it will not work if the size of the range is not equal:
template <typename IITR1, typename IITR2>
bool equivalent(IITR1 first1, IITR1 last1, IITR2 first2, IITR2 last2)
{
return equal(first1, last1, first2) && equal(first2, last2, first1);
}