Namespaces
Variants

std::count, std::count_if

С ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Последовательные операции без изменения    
Групповые операции
(C++17)
Операции поиска
Последовательные операции с изменением
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разбиения
(C++11)    

Операции сортировки
Операции бинарного поиска
(на разбитых диапазонах)
Операции над множествами (на отсортированных диапазонах)
Операции слияния (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для демонстрации*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определён в заголовке <algorithm>
template< class InputIt, class T >
typename std::iterator_traits<InputIt>::difference_type
    count( InputIt first, InputIt last, const T& value );
(1) (до C++26)
(constexpr начиная с C++20)
template< class InputIt, class T = typename std::iterator_traits
                                       <InputIt>::value_type >
constexpr typename std::iterator_traits<InputIt>::difference_type
    count( InputIt first, InputIt last, const T& value );
(начиная с C++26)
template< class ExecutionPolicy, class ForwardIt, class T >
typename std::iterator_traits<ForwardIt>::difference_type
    count( ExecutionPolicy&& policy,
           ForwardIt first, ForwardIt last, const T& value );
(2) (начиная с C++17)
(до C++26)
template< class ExecutionPolicy,
          class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type >
typename std::iterator_traits<ForwardIt>::difference_type
    count( ExecutionPolicy&& policy,
           ForwardIt first, ForwardIt last, const T& value );
(начиная с C++26)
template< class InputIt, class UnaryPred >
typename std::iterator_traits<InputIt>::difference_type
    count_if( InputIt first, InputIt last, UnaryPred p );
(3) (constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >
typename std::iterator_traits<ForwardIt>::difference_type
    count_if( ExecutionPolicy&& policy,
              ForwardIt first, ForwardIt last, UnaryPred p );
(4) (начиная с C++17)

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

1) Подсчитывает элементы, равные value (используя operator==).
3) Подсчитывает элементы, для которых предикат p возвращает true.
2,4) То же, что и (1,3), но выполняется в соответствии с policy.
Эти перегрузки участвуют в разрешении перегрузки только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)

Параметры

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

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

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

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

Количество итераторов it в диапазоне [first, last), удовлетворяющих следующему условию:

1,2) *it == value равно true.
3,4) p(*it) != false равно true.

Сложность

Пусть N — это std::distance(first, last):

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

Исключения

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

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

Примечания

Для получения количества элементов в диапазоне [first, last) без дополнительных критериев см. std::distance.

Макрос проверки возможности Значение Std Возможность
__cpp_lib_algorithm_default_value_type 202403 (C++26) Списочная инициализация для алгоритмов (1,2)

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

См. также реализации count в libstdc++ и libc++.

См. также реализации count_if в libstdc++ и libc++.


count (1)
template<class InputIt, class T = typename std::iterator_traits<InputIt>::value_type>
typename std::iterator_traits<InputIt>::difference_type
    count(InputIt first, InputIt last, const T& value)
{
    typename std::iterator_traits<InputIt>::difference_type ret = 0;
    for (; first != last; ++first)
        if (*first == value)
            ++ret;
    return ret;
}
count_if (3)
template<class InputIt, class UnaryPred>
typename std::iterator_traits<InputIt>::difference_type
    count_if(InputIt first, InputIt last, UnaryPred p)
{
    typename std::iterator_traits<InputIt>::difference_type ret = 0;
    for (; first != last; ++first)
        if (p(*first))
            ++ret;
    return ret;
}

Пример

#include <algorithm>
#include <array>
#include <cassert>
#include <complex>
#include <iostream>
#include <iterator>

int main()
{
    constexpr std::array v{1, 2, 3, 4, 4, 3, 7, 8, 9, 10};
    std::cout << "v: ";
    std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
    
    // Determine how many integers match a target value.
    for (const int target : {3, 4, 5})
    {
        const int num_items = std::count(v.cbegin(), v.cend(), target);
        std::cout << "number: " << target << ", count: " << num_items << '\n';
    }
    
    // Use a lambda expression to count elements divisible by 4.
    int count_div4 = std::count_if(v.begin(), v.end(), [](int i) { return i % 4 == 0; });
    std::cout << "numbers divisible by four: " << count_div4 << '\n';
    
    // A simplified version of `distance` with O(N) complexity:
    auto distance = [](auto first, auto last)
    {
        return std::count_if(first, last, [](auto) { return true; });
    };
    static_assert(distance(v.begin(), v.end()) == 10);

    std::array<std::complex<double>, 3> nums{{{4, 2}, {1, 3}, {4, 2}}};
    #ifdef __cpp_lib_algorithm_default_value_type
        // T gets deduced making list-initialization possible
        auto c = std::count(nums.cbegin(), nums.cend(), {4, 2});
    #else
        auto c = std::count(nums.cbegin(), nums.cend(), std::complex<double>{4, 2});
    #endif
    assert(c == 2);
}

Вывод:

v: 1 2 3 4 4 3 7 8 9 10
number: 3, count: 2
number: 4, count: 2
number: 5, count: 0
numbers divisible by four: 3

Отчёты о дефектах

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

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

См. также

возвращает расстояние между двумя итераторами
(шаблон функции)
возвращает количество элементов, удовлетворяющих определённым критериям
(объект функции алгоритма)