定義により、std::equal アルゴリズムは「最後の」反復子を 1 つだけ取ります。stackoverflow に関する多くの投稿は、2 つの範囲間で同等性を実行するには、std::equal を呼び出すことに加えて、範囲が同じサイズであることを最初に確認する必要があることを示しています。ランダム アクセス反復子が使用可能な場合、これによって材料のオーバーヘッドが追加されることはありません。ただし、ランダム アクセス イテレータがないと、既存の STL アルゴリズムのみで実装された最初のコード フラグメントは、カスタムの「同等の」アルゴリズム (STL の一部ではない) を表す 2 番目のコード フラグメントよりも遅くなるようです。私の質問は、フラグメント 2 は、既存の STL アルゴリズムのみを使用してコーディングされたどのアルゴリズムよりも効率的ですか? もしそうなら、なぜこのアルゴリズムは STL の一部ではないのですか?
フラグメント 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 );
}
フラグメント 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;
}
注: 私はチェックしていませんが、コンパイラーがフラグメント 1 を最適化して、フラグメント 2 と同じパフォーマンスのコードを生成するかどうかは非常に疑わしいと思います。
完全を期すために、次のコード フラグメントは、範囲のサイズが等しくない場合に失敗するため、ほとんど役に立ちません。
template <typename IITR1, typename IITR2>
bool equivalent(IITR1 first1, IITR1 last1, IITR2 first2, IITR2 last2)
{
return equal(first1, last1, first2) && equal(first2, last2, first1);
}