Namespaces
Variants

std::ranges::equal

ja.cppreference.net より
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとレンジ上のアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
ソートおよび関連操作
分割操作
(C++11)    

ソート操作
二分探索操作
(分割された範囲に対する)
集合操作 (ソート済み範囲に対する)
マージ操作 (ソート済み範囲に対する)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作


 
制約付きアルゴリズム
このメニューのすべての名前は名前空間 std::ranges
非変更シーケンス操作
変更シーケンス操作
分割操作
ソート操作
二分探索操作 (ソート済み範囲に対する)
       
       
集合操作 (ソート済み範囲に対する)
ヒープ操作
最小/最大操作
       
       
順列操作
畳み込み操作
数値操作
(C++23)            
未初期化ストレージ上の操作
戻り値の型
 
ヘッダ <algorithm>
で定義
template< std::input_iterator I1, std::sentinel_for<I1> S1,
          std::input_iterator I2, std::sentinel_for<I2> S2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
constexpr bool
    equal( I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
           Proj1 proj1 = {}, Proj2 proj2 = {} );
(1) (C++20以降)
template< ranges::input_range R1, ranges::input_range R2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::indirectly_comparable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                                    Pred, Proj1, Proj2>
constexpr bool
    equal( R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
(2) (C++20以降)
1) 範囲 true の射影された値が範囲 [first1, last1) の射影された値と等しい場合は [first2, last2) を返し、そうでなければ false を返す。
2) (1) と同じだが、r をソース範囲として使用する。あたかも ranges::begin(r) を first として、ranges::end(r) を last として使用したかのように振る舞う。

2つの範囲は、同じ数の要素を持ち、対応する射影された要素のすべてのペアが pred を満たす場合に等しいと見なされる。すなわち、std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2)) は両方の範囲の対応する要素のすべてのペアについて true を返す。

このページで説明されている関数のようなエンティティは、アルゴリズム関数オブジェクト (非公式には niebloids として知られる) である。すなわち:

パラメータ

first1, last1 - 比較対象の最初の要素範囲を定義する 範囲 のイテレータ-番兵ペア
r1 - 比較対象の最初の要素範囲
first2, last2 - 比較対象の2番目の要素範囲を定義する 範囲 のイテレータ-番兵ペア
r2 - 比較対象の2番目の要素範囲
pred - 投影された要素に適用する二項述語
proj1 - 最初の要素範囲に適用する投影
proj2 - 2番目の要素範囲に適用する投影

戻り値

範囲 [ first1 , last1 ) の長さが範囲 [ first2 , last2 ) の長さと等しくない場合、 false を返します。

2つの範囲の要素が射影後に等しい場合、 true を返します。

それ以外の場合、 false を返します。

注記

ranges::equal は、 std::unordered_set 、 std::unordered_multiset 、 std::unordered_map 、または std::unordered_multimap のイテレータによって形成される範囲を比較するために使用すべきではありません。なぜなら、これらのコンテナに格納される要素の順序は、たとえ2つのコンテナが同じ要素を格納している場合でも異なる可能性があるためです。

コンテナ全体または文字列ビューを等価性で比較する場合、 operator == が通常推奨されます。

ranges::equal は短絡保証されません。例えば、両範囲の最初の要素ペアが等しくない場合でも、残りの要素も比較される可能性があります。非短絡比較は、範囲が std::memcmp または実装固有のベクトル化アルゴリズムで比較される場合に発生する可能性があります。

計算量

最大で min ( last1 - first1, last2 - first2 ) 回の述語と対応する射影の適用。

しかし、 S1 と S2 がそれぞれのイテレータに対して std::sized_sentinel_for をモデル化しており、かつ last1 - first1 ! = last2 - first2 の場合、述語の適用は一切行われません(サイズ不一致は要素を一切参照せずに検出されます)。

実装例

struct equal_fn
{
  template<std::input_iterator I1, std::sentinel_for<I1> S1,
           std::input_iterator I2, std::sentinel_for<I2> S2,
           class Pred = ranges::equal_to,
           class Proj1 = std::identity, class Proj2 = std::identity>
  requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
  constexpr bool
      operator()(I1 first1, S1 last1, I2 first2, S2 last2,
                 Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
  {
      if constexpr (std::sized_sentinel_for<S1, I1> and std::sized_sentinel_for<S2, I2>)
          if (std::ranges::distance(first1, last1) != std::ranges::distance(first2, last2))
              return false;
      for (; first1 != last1; ++first1, (void)++first2)
          if (!std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2)))
              return false;
      return true;
  }
  template<ranges::input_range R1, ranges::input_range R2,
           class Pred = ranges::equal_to,
           class Proj1 = std::identity, class Proj2 = std::identity>
  requires std::indirectly_comparable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                                      Pred, Proj1, Proj2>
  constexpr bool
      operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
  {
      return (*this)(ranges::begin(r1), ranges::end(r1),
                     ranges::begin(r2), ranges::end(r2),
                     std::ref(pred), std::ref(proj1), std::ref(proj2));
  }
};
inline constexpr equal_fn equal;

例

以下のコードは ranges::equal を使用して、文字列が回文かどうかをテストします。

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <ranges>
#include <string_view>
constexpr bool is_palindrome(const std::string_view s)
{
    namespace views = std::views;
    auto forward = s | views::take(s.size() / 2);
    auto backward = s | views::reverse | views::take(s.size() / 2);
    return std::ranges::equal(forward, backward);
}
void test(const std::string_view s)
{
    std::cout << std::quoted(s) << " is "
              << (is_palindrome(s) ? "" : "not ")
              << "a palindrome\n";
}
int main()
{
    test("radar");
    test("hello");
    static_assert(is_palindrome("ABBA") and not is_palindrome("AC/DC"));
}

出力:

"radar" is a palindrome
"hello" is not a palindrome

関連項目

特定の条件を満たす最初の要素を検索する
(アルゴリズム関数オブジェクト)
2つの範囲を辞書的に比較する
(アルゴリズム関数オブジェクト)
2つの範囲が異なる最初の位置を検索する
(アルゴリズム関数オブジェクト)
要素の範囲の最初の出現を検索する
(アルゴリズム関数オブジェクト)
二分探索を使用して指定された値に一致する要素の範囲を検索する
(アルゴリズム関数オブジェクト)
実装する関数オブジェクト x == y
(クラステンプレート)
2つの要素セットが同じかどうかを判定する
(関数テンプレート)