std::search_n
| ヘッダー <algorithm> で定義 |
||
| (1) | ||
template< class ForwardIt, class Size, class T > ForwardIt search_n( ForwardIt first, ForwardIt last, |
(C++20 以降 constexpr) (C++26まで) |
|
| template< class ForwardIt, class Size, class T = typename std::iterator_traits |
(C++26以降) | |
| (2) | ||
| template< class ExecutionPolicy, class ForwardIt, class Size, class T > |
(C++17以降) (C++26まで) |
|
| template< class ExecutionPolicy, class ForwardIt, class Size, |
(C++26以降) | |
| (3) | ||
template< class ForwardIt, class Size, class T, class BinaryPred > ForwardIt search_n( ForwardIt first, ForwardIt last, |
(C++20 以降 constexpr) (C++26まで) |
|
| template< class ForwardIt, class Size, class T = typename std::iterator_traits |
(C++26以降) | |
| (4) | ||
| template< class ExecutionPolicy, class ForwardIt, class Size, class T, class BinaryPred > |
(C++17以降) (C++26まで) |
|
| template< class ExecutionPolicy, class ForwardIt, class Size, class T = typename std::iterator_traits |
(C++26以降) | |
範囲 [first, last) 内で、指定された value と等しい要素が count 個連続する最初のシーケンスを検索します。
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true である。 |
(C++20まで) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> は true です。 |
(C++20以降) |
目次 |
[edit] パラメータ
| first, last | - | 検査する要素の範囲を定義するイテレータのペア |
| count | - | 検索するシーケンスの長さ |
| value | - | 検索する要素の値 |
| policy | - | 使用する 実行ポリシー |
| p | - | 要素が等しいと見なされる場合に true を返す二項述語。 述語関数のシグネチャは、以下と同等である必要がある。 bool pred(const Type1 &a, const Type2 &b); シグネチャは const & を持つ必要はないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関わらず、(おそらく const の) |
| 型要件 | ||
-ForwardIt は LegacyForwardIterator の要件を満たさなければなりません。 | ||
-BinaryPred は BinaryPredicate の要件を満たす必要がある。 | ||
-Size は、変換可能な 整数型でなければなりません。 | ||
[edit] 戻り値
count が正の場合、範囲 [first, last) 内で見つかった最初のシーケンスの先頭を指すイテレータを返します。シーケンス内の各イテレータ it は、次の条件を満たす必要があります。
そのようなシーケンスが見つからない場合、last が返されます。
count がゼロまたは負の場合、first が返されます。
[edit] 計算量
std::distance(first, last) を N とする
[edit] 例外
ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外をスローし、
ExecutionPolicyが 標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他のExecutionPolicyの場合、動作は実装定義です。 - アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。
[edit] 可能な実装
| search_n (1) |
|---|
template<class ForwardIt, class Size, class T = typename std::iterator_traits<ForwardIt>::value_type> ForwardIt search_n(ForwardIt first, ForwardIt last, Size count, const T& value) { if (count <= 0) return first; for (; first != last; ++first) { if (!(*first == value)) continue; ForwardIt candidate = first; for (Size cur_count = 1; true; ++cur_count) { if (cur_count >= count) return candidate; // success ++first; if (first == last) return last; // exhausted the list if (!(*first == value)) break; // too few in a row } } return last; } |
| search_n (3) |
template<class ForwardIt, class Size, class T = typename std::iterator_traits<ForwardIt>::value_type, class BinaryPred> ForwardIt search_n(ForwardIt first, ForwardIt last, Size count, const T& value, BinaryPred p) { if (count <= 0) return first; for (; first != last; ++first) { if (!p(*first, value)) continue; ForwardIt candidate = first; for (Size cur_count = 1; true; ++cur_count) { if (cur_count >= count) return candidate; // success ++first; if (first == last) return last; // exhausted the list if (!p(*first, value)) break; // too few in a row } } return last; } |
[edit] 注釈
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type |
202403 |
(C++26) | リスト初期化(バージョン 1-4) |
[edit] 例
#include <algorithm> #include <cassert> #include <complex> #include <iostream> #include <iterator> #include <vector> template<class Container, class Size, class T> constexpr bool consecutive_values(const Container& c, Size count, const T& v) { return std::search_n(std::begin(c), std::end(c), count, v) != std::end(c); } int main() { constexpr char sequence[] = ".0_0.000.0_0."; static_assert(consecutive_values(sequence, 3, '0')); for (int n : {4, 3, 2}) std::cout << std::boolalpha << "Has " << n << " consecutive zeros: " << consecutive_values(sequence, n, '0') << '\n'; std::vector<std::complex<double>> nums{{4, 2}, {4, 2}, {1, 3}}; #ifdef __cpp_lib_algorithm_default_value_type auto it = std::search_n(nums.cbegin(), nums.cend(), 2, {4, 2}); #else auto it = std::search_n(nums.cbegin(), nums.cend(), 2, std::complex<double>{4, 2}); #endif assert(it == nums.begin()); }
出力
Has 4 consecutive zeros: false Has 3 consecutive zeros: true Has 2 consecutive zeros: true
[edit] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 283 | C++98 | T は EqualityComparable であることが求められていましたが、InputIt の値型が常に T ではない |
要件が削除されました |
| LWG 426 | C++98 | 計算量の最大値が N·count であったcount が負の場合、負になる |
上限は 0count が非正の場合 |
| LWG 714 | C++98 | count > 0 の場合、計算量の最大値は N·count であったが、最悪の場合、比較/操作の回数は常に N |
上限を変更した この場合、上限を N にした |
| LWG 2150 | C++98 | 「シーケンス出現」の条件が正しくなかった | 修正済み |
[edit] 関連項目
| 特定の範囲内で最後の要素のシーケンスを見つける (関数テンプレート) | |
| (C++11) |
特定の基準を満たす最初の要素を見つける (関数テンプレート) |
| 要素の範囲の最初の出現を検索する (関数テンプレート) | |
| (C++20) |
範囲内である要素が連続して出現する最初の箇所を検索する (アルゴリズム関数オブジェクト) |