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 | - | 소스 범위 |
| 를 정의하는 반복자 쌍 | - | 요소를 비교할 값 |
| p | - | 단항 술어로, 필요한 요소에 대해 true을 반환합니다. 표현식 |
| q | - | 단항 술어로, 필요한 요소에 대해 false을 반환합니다. 표현식 |
| policy | - | 사용할 실행 정책 |
| 타입 요구 사항 | ||
-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) |
특정 기준을 만족하는 첫 번째 요소를 찾습니다 (알고리즘 함수 객체) |
| 첫 번째로 인접한 두 항목이 같거나 주어진 조건을 만족하는 것을 찾습니다 (함수 템플릿 & 알고리즘 함수 객체) | |
(C++20) |
|
| 일정 범위에서 요소의 마지막 시퀀스를 찾습니다 (함수 템플릿 & 알고리즘 함수 객체) | |
(C++20) |
|
| 요소 집합 중 하나를 검색합니다 (함수 템플릿 & 알고리즘 함수 객체) | |
(C++20) |
|
| 두 범위가 다른 첫 번째 위치를 찾습니다 (함수 템플릿 & 알고리즘 함수 객체) | |
(C++20) |
|
| 요소 범위의 첫 번째 발생을 검색합니다 (함수 템플릿 & 알고리즘 함수 객체) | |
(C++20) |