std::find, std::find_if, std::find_if_not
| ヘッダ <algorithm>
|
||
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
|
で定義 (1) | (C++20 から constexpr) (C++26 まで) |
template< class InputIt, class T = typename std::iterator_traits
<InputIt>::value_type >
constexpr InputIt find( InputIt first, InputIt last, const T& value );
|
(C++26 から) | |
template< class InputIt, class UnaryPred >
InputIt find_if( InputIt first, InputIt last, UnaryPred p );
|
(2) | (C++20 から constexpr) |
template< class InputIt, class UnaryPred >
InputIt find_if_not( InputIt first, InputIt last, UnaryPred q );
|
(3) | (C++11 から) (C++20 から constexpr) |
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt find( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, const T& value );
|
(4) | (C++17 から) (C++26 まで) |
template< class ExecutionPolicy,
class ForwardIt, class T = typename std::iterator_traits
<ForwardIt>::value_type >
ForwardIt find( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, const T& value );
|
(C++26 から) | |
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
ForwardIt find_if( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryPred p );
|
(5) | (C++17 から) |
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
ForwardIt find_if_not( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryPred q );
|
(6) | (C++17 から) |
ソース範囲 [first, last) 内の、特定の条件を満たす最初の要素を指すイテレータを返します(そのようなイテレータがない場合は last を返します)。
find value と等しい(operator== を使用して)最初の要素を検索します。find_if 述語 p が true を返す最初の要素を検索します。find_if_not 述語 q が false を返す最初の要素を検索します。policy に従って実行されます。true である場合にのみオーバーロード解決に参加します。
|
|
(C++20 まで) |
|
|
(C++20 から) |
引数
| first, last | - | コピー元の範囲 |
| を定義するイテレータのペア | value | - |
| 要素と比較する値 | p | -
true要求された要素に対して を返す単項述語。 |
| q | - | 要求された要素に対して falseを返す単項述語。 は、 |
| - | 使用する | 実行ポリシー |
| 型要件 | ||
-InputItはLegacyInputIteratorの要件を満たさなければならない。
| ||
-ForwardItはLegacyForwardIteratorの要件を満たさなければならない。
| ||
-UnaryPredicateはPredicateの要件を満たさなければならない。
| ||
戻り値
以下の条件を満たすソース範囲内の最初のイテレータ it。そのようなイテレータが存在しない場合は last。
*it == value は true である。p(*it) は true である。q(*it) は false である。計算量
ここで、N はstd::distance(first, last)とする:
value を使用し、operator== を用いる)。p の適用。q の適用。value を使用し、operator== を用いる)。p の適用。q の適用。例外
- 並列化に必要な一時メモリリソースが利用できない場合、std::bad_alloc が送出される。
- アルゴリズムの引数を介してオブジェクトにアクセス中に捕捉されない例外が発生した場合、その動作は実行ポリシーによって決定される(標準ポリシーの場合、std::terminate が呼び出される)。
実装例
| find |
|---|
template<class InputIt, class T = typename std::iterator_traits<InputIt>::value_type>
constexpr InputIt find(InputIt first, InputIt last, const T& value)
{
for (; first != last; ++first)
if (*first == value)
return first;
return last;
}
|
| find_if |
template<class InputIt, class UnaryPred>
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPred p)
{
for (; first != last; ++first)
if (p(*first))
return first;
return last;
}
|
| find_if_not |
template<class InputIt, class UnaryPred>
constexpr InputIt find_if_not(InputIt first, InputIt last, UnaryPred q)
{
for (; first != last; ++first)
if (!q(*first))
return first;
return last;
}
|
注記
C++11 が利用できない場合、std::find_if_not の代替として、否定された述語を指定した std::find_if を使用できます。
template<class InputIt, class UnaryPred>
InputIt find_if_not(InputIt first, InputIt last, UnaryPred q)
{
return std::find_if(first, last, std::not1(q));
}
|
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type |
202403 |
(C++26) | アルゴリズムの 初期化リスト (1,4) |
例
以下の例は、指定されたシーケンス内の数値を見つけます。
#include <algorithm>
#include <array>
#include <cassert>
#include <complex>
#include <initializer_list>
#include <iostream>
#include <vector>
bool is_even(int i)
{
return i % 2 == 0;
}
void example_contains()
{
const auto haystack = {1, 2, 3, 4};
for (const int needle : {3, 5})
if (std::find(haystack.begin(), haystack.end(), needle) == haystack.end())
std::cout << "haystack does not contain " << needle << '\n';
else
std::cout << "haystack contains " << needle << '\n';
}
void example_predicate()
{
for (const auto& haystack : {std::array{3, 1, 4}, {1, 3, 5}})
{
const auto it = std::find_if(haystack.begin(), haystack.end(), is_even);
if (it != haystack.end())
std::cout << "haystack contains an even number " << *it << '\n';
else
std::cout << "haystack does not contain even numbers\n";
}
}
void example_list_init()
{
std::vector<std::complex<double>> haystack{{4.0, 2.0}};
#ifdef __cpp_lib_algorithm_default_value_type
// T gets deduced making list-initialization possible
const auto it = std::find(haystack.begin(), haystack.end(), {4.0, 2.0});
#else
const auto it = std::find(haystack.begin(), haystack.end(), std::complex{4.0, 2.0});
#endif
assert(it == haystack.begin());
}
int main()
{
example_contains();
example_predicate();
example_list_init();
}
出力:
haystack contains 3
haystack does not contain 5
haystack contains an even number 4
haystack does not contain even numbers
欠陥報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 283 | C++98 |
T
は
EqualityComparable
であることが要求されていたが、
InputIt
の値型が
T
ではない可能性がある
|
要求を削除 |
関連項目
(C++20)(C++20)(C++20) |
特定の基準を満たす最初の要素を検索する (アルゴリズム関数オブジェクト) |
| 等しい(または指定された述語を満たす)最初の隣接する2つの要素を検索する (関数テンプレート & アルゴリズム関数オブジェクト) | |
(C++20) |
|
| ある範囲内で最後に出現する要素のシーケンスを検索する (関数テンプレート & アルゴリズム関数オブジェクト) | |
(C++20) |
|
| 要素の集合の中のいずれかを検索する (関数テンプレート & アルゴリズム関数オブジェクト) | |
(C++20) |
|
| 2つの範囲が最初に異なる位置を見つける (関数テンプレート & アルゴリズム関数オブジェクト) | |
(C++20) |
|
| 要素の範囲が最初に出現する位置を検索する (関数テンプレート & アルゴリズム関数オブジェクト) | |
(C++20) |