Spec-Zone.ru › C++

std::find, std::find_if, std::find_if_not

Определено в заголовке <algorithm>
(1)
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
(до C++20)
template< class InputIt, class T >
constexpr InputIt find( InputIt first, InputIt last, const T& value );
(с C++20)
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt find( ExecutionPolicy&& policy,
                ForwardIt first, ForwardIt last, const T& value );
(2) (с C++17)
(3)
template< class InputIt, class UnaryPredicate >
InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );
(до C++20)
template< class InputIt, class UnaryPredicate >
constexpr InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );
(с C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt find_if( ExecutionPolicy&& policy,
                   ForwardIt first, ForwardIt last, UnaryPredicate p );
(4) (с C++17)
(5)
template< class InputIt, class UnaryPredicate >
InputIt find_if_not( InputIt first, InputIt last, UnaryPredicate q );
(с C++11)
(до C++20)
template< class InputIt, class UnaryPredicate >
constexpr InputIt find_if_not( InputIt first, InputIt last, UnaryPredicate q );
(с C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt find_if_not( ExecutionPolicy&& policy,
                       ForwardIt first, ForwardIt last, UnaryPredicate q );
(6) (с C++17)

Возвращает итератор на первый элемент в диапазоне [first, last) , удовлетворяющий определённым критериям (или last если такого итератора нет):

1) find ищет элемент, равный value (используя operator==).
3) find_if ищет элемент, для которого предикат p возвращает true.
5) find_if_not ищет элемент, для которого предикат q возвращает false.
2,4,6) Аналогично (1,3,5), но выполняется согласно policy. Эти перегрузки не участвуют в разрешении перегрузки, если

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)

Параметры

first, last - диапазон элементов для проверки
value - значение для сравнения с элементами
policy - политика выполнения. См. политику выполнения для подробностей.
p - унарный предикат, возвращающий ​true для требуемого элемента.

Выражение p(v) должно быть приводимо к типу bool для каждого аргумента v типа (возможно const) VT, где VT — тип значения InputIt, независимо от категории значения, и не должно изменять v. Таким образом, тип параметра VT& недопустим, так же как и VT за исключением случаев, когда для VT перемещение эквивалентно копированию(с C++11). ​

q - унарный предикат, возвращающий ​false для требуемого элемента.

Выражение q(v) должно быть приводимо к типу bool для каждого аргумента v типа (возможно const) VT, где VT — тип значения InputIt, независимо от категории значения, и не должно изменять v. Таким образом, тип параметра VT& недопустим, так же как и VT за исключением случаев, когда для VT перемещение эквивалентно копированию(с C++11). ​

Требования к типу
-InputIt должен соответствовать требованиям LegacyInputIterator.
-ForwardIt должен соответствовать требованиям LegacyForwardIterator.
-UnaryPredicate должен соответствовать требованиям Predicate.

Возвращаемое значение

Первый итератор it в диапазоне диапазон [first, last) удовлетворяющий следующему условию, или last если такого итератора нет:

1,2) *it == value является true.
3,4) p(*it) является true.
5,6) q(*it) является false.

Сложность

Дано N как std::distance(first, last):

1,2) Максимум N сравнений с value используя operator==.
3,4) Максимум N применений предиката p.
5,6) Максимум N применений предиката q.

Исключение

Перегрузки с параметром шаблона, названным ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение функции, вызываемой как часть алгоритма, вызывает исключение, и ExecutionPolicy — одна из стандартных политик, std::terminate вызывается. Для любой другой ExecutionPolicy, поведение определяется реализацией.
  • Если алгоритм не удаётся выделить память, выбрасывается std::bad_alloc.

Возможная реализация

find
template<class InputIt, class T>
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 UnaryPredicate>
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
    for (; first != last; ++first)
        if (p(*first))
            return first;
 
    return last;
}
find_if_not
template<class InputIt, class UnaryPredicate>
constexpr InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate 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 UnaryPredicate>
InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate q)
{
    return std::find_if(first, last, std::not1(q));
}

Пример

В следующем примере ищутся целые числа в заданном std::vector.

#include <algorithm>
#include <array>
#include <iostream>
 
int main()
{
    const auto v = {1, 2, 3, 4};
 
    for (const int n : {3, 5})
        (std::find(v.begin(), v.end(), n) == std::end(v))
            ? std::cout << "v does not contain " << n << '\n'
            : std::cout << "v contains " << n << '\n';
 
    auto is_even = [](int i) { return i % 2 == 0; };
 
    for (auto const& w : {std::array{3, 1, 4}, {1, 3, 5}})
        if (auto it = std::find_if(begin(w), end(w), is_even); it != std::end(w))
            std::cout << "w contains an even number " << *it << '\n';
        else
            std::cout << "w does not contain even numbers\n";
}

Вывод:

v contains 3
v does not contain 5
w contains an even number 4
w does not contain even numbers

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применён к Поведение, как опубликовано Корректное поведение
LWG 283 C++98 T должно было быть EqualityComparable, но
тип значения InputIt не всегда T
убрано требование

См. также

adjacent_find
находит первые два смежных элемента, которые равны (или удовлетворяют заданному предикату)
(шаблон функции)
find_end
находит последнюю последовательность элементов в определённом диапазоне
(шаблон функции)
find_first_of
ищет любой из набора элементов
(шаблон функции)
mismatch
находит первую позицию, где два диапазона различаются
(шаблон функции)
search
ищет диапазон элементов
(шаблон функции)
ranges::findranges::find_ifranges::find_if_not
(C++20)(C++20)(C++20)
находит первый элемент, удовлетворяющий определённым критериям
(niebloid)
END_OF_DOCUMENT_MARKER

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/find

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API