# Counting Algorithms

An introduction to the 5 main counting algorithms in the C++ standard library: count(), count_if(), any_of(), none_of(), and all_of()
This lesson is part of theÂ course:

### Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, Unlimited Access
###### Ryan McCombe
Updated

Let's take a look at some useful counting algorithms available in the standard library. To access these, we need the <algorithm>Â header:

#include <algorithm>

In this lesson, we cover the 5 most useful counting algorithms: count(), count_if(), any_of(), none_of() and all_of(). Let's getÂ started!

## std::ranges::count()

The std::ranges::count algorithm requires two arguments - the range we want to run the algorithm in, and the element we want to count within thatÂ range.

Whether or not an element matches what weâ€™re looking for is determined by an equality check. Therefore, the type of elements in our collection must implement the equality operator, ==

In this example, we count the number of 4s in our vector ofÂ integers:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers { 1, 2, 3, 4, 4, 5 };
auto Fours { std::ranges::count(Numbers, 4) };
std::cout << "Count of fours: " << Fours;
}
Count of fours: 2

### Return Type

The return type of these algorithms can be somewhat cryptic. For count(), the return type is aÂ template:

std::ranges::range_difference_t

Given weâ€™re counting elements in a std::vector<int> in this case, the type returned from count() would be even moreÂ verbose:

std::ranges::range_difference_t<std::vector<int>> Fours
{
std::ranges::count(Numbers, 4)
};

Itâ€™s common to just use auto in this scenario, as we did in the original example. Alternatively, itâ€™s reasonable to implicitly cast the return value to something simpler, like a 64-bit integer or size_t:

int64_t Fours { std::ranges::count(Numbers, 4) };

## std::ranges::count_if()

The basic std::ranges::count() algorithm uses the equality operator == to determine if an element in our container matches the object weâ€™re lookingÂ for.

The std::ranges::count_if() algorithm lets us change this behavior. Rather than using the == operator to determine if two objects are equal, count_if() uses a function, which we provide as anÂ argument.

The function will be called for every object in the collection, receiving that object as an argument. Our function should return true if we want this object to be included in the count, and false otherwise. A function that returns a boolean is also known as a predicate.

Below, we have a predicate that returns true if a provided argument is even. We pass this predicate to std::ranges::count_if() to count the number of elements in our range that areÂ even:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers { 1, 2, 3, 4, 4, 5 };
auto isEven{[](int x) { return x % 2 == 0; }};
auto EvenCount {
std::ranges::count_if(Numbers, isEven)
};
std::cout << "Even Count: " << EvenCount;
}
Even Count: 3

## std::ranges::any_of()

The std::ranges::any_of() algorithm also accepts a predicate function. The algorithm will return true if our predicate returns true for any element in theÂ range.

In the following example, we return true if any number in our collection isÂ even:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers { 1, 2, 3, 4, 4, 5 };
auto isEven{[](int x) { return x % 2 == 0; } };
bool IncludesEven {
std::ranges::any_of(Numbers, isEven)};

std::cout << "An even number "
<< (IncludesEven ? "is" : "is not")
<< " included";
}
An even number is included

### count_if() vs any_of()

Algorithms like any_of() may seem unnecessary, as we can get the same output with count_if:

bool IncludesEven {
std::ranges::count_if(Numbers, isEven) > 0
};

Using any_of() here would have twoÂ advantages:

• It better describes what our code is determining
• It results in better performance. After finding an even number, count_if() function continues to check the rest of our collection, even though doing so will not change the result of IncludesEven. any_of() stops as soon as it finds an object that causes our predicate to return true.

Similar arguments are also true of the none_of() and all_of() algorithms, which weâ€™ll seeÂ next.

## std::ranges::none_of()

The std::ranges::none_of() algorithm will run a predicate on everything in our collection, and return true if every predicate returns false.

If our predicate returns true for any element in the collection, the algorithm will stop evaluating further elements, and return false.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers { 1, 2, 3, 4, 4, 5 };
auto isEven{ [](int x) { return x % 2 == 0; } };
bool NoEvenNumbers {
std::ranges::none_of(Numbers, isEven)};

std::cout << "The range contains "
<< (NoEvenNumbers ? "no" : "some")
<< " even numbers";
}
The range contains some even numbers

This algorithm will return true if the range has noÂ elements:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector<int> Numbers { };
auto isEven { [](int x) { return x % 2 == 0; } };
bool Result {
std::ranges::none_of(Numbers, isEven)};

std::cout << (Result ? "true" : "false");
}
true

## std::ranges::all_of()

The std::ranges::all_of() algorithm will run a predicate on everything in our collection, and return true if every invocation of the predicate returns true.

If our predicate returns false for any element in the collection, the algorithm will stop evaluating further elements, and return false.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers { 1, 2, 3, 4, 4, 5 };
auto isEven{[](int x) { return x % 2 == 0; }};
bool AllEvenNumbers {
std::ranges::all_of(Numbers, isEven)};

std::cout << "The range is "
<< (AllEvenNumbers ? "all" : "NOT all")
<< " even numbers";
}
The range is NOT all even numbers

Note, that this algorithm will return true if the range has noÂ elements:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector<int> Numbers{};
auto isEven{[](int x) { return x % 2 == 0; }};
bool Result{
std::ranges::all_of(Numbers, isEven)};

std::cout << Result ? "true" : "false";
}
true

## Using Member Functions as Predicates

Typically when using these algorithms, the predicates we need will be class methods of the objects contained within our range. When that is the case, we generally donâ€™t need to define a predicate function. We can just pass a reference to the classÂ method:

#include <algorithm>
#include <iostream>
#include <vector>

class Player {/*...*/};

int main() {
std::vector Party {
Player{"Roderick", 100},
Player{"Anna", 200},
Player{"Robert", 500}
};

bool EveryoneAlive{std::ranges::all_of(
Party, &Player::isAlive)};

std::cout << "Everyone "
<< (EveryoneAlive ? "is" : "is not")
<< " alive";
}
Everyone is alive

## Projection

All the algorithms in this lesson accept an additional optional argument, which can be a projection function. We cover projection in detailÂ here:

In this example, we project the objects in our container to their absolute value before running the count() algorithm. Two of those projections are equal to 1, so our algorithm returns 2:

#include <algorithm>
#include <iostream>
#include <vector>

int Projector(int x) { return std::abs(x); }

int main() {
std::vector Nums{-2, -1, 0, 1, 2};

auto Count {std::ranges::count(
Nums, 1, Projector)};

std::cout << "Count: " << Count;
}
Count: 2

In this example, we use Player::GetName() as our projection function, projecting our Player objects to a std::string before comparing them to the "Anna"Â string:

#include <algorithm>
#include <iostream>
#include <vector>

class Player {/*...*/};

int main() {
std::vector Party {
Player{"Roderick", 100},
Player{"Anna", 200},
Player{"Robert", 500}
};

auto AnnaCount{std::ranges::count(
Party, "Anna", &Player::GetName)};

std::cout << "AnnaCount: " << AnnaCount;
}
AnnaCount: 1

## Using Iterators

As we covered in the introduction to range-based algorithms, std::ranges::count() and all the other algorithms we covered in this lesson allow us to define our range as an iterator-sentinelÂ pair.

Below, we use this technique to exclude the first and last objects from ourÂ count:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers{1, 2, 3, 4, 4};
auto Fours{std::ranges::count(
Numbers.begin() + 1, Numbers.end() - 1, 4)};

std::cout << "Count of fours: " << Fours;
}
Count of fours: 1

The concept of a range was introduced in C++20. When targeting older specifications, we can use alternative versions of these algorithms that work directly with iteratorsÂ instead.

These are available by omitting the ranges qualification from the identifiers. For example, the iterator variant of std::ranges::count() is available as std::count():

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Numbers{1, 2, 3, 4, 4, 5};
auto Fours{std::count(
Numbers.begin(), Numbers.end(), 4)};

std::cout << "Count of fours: " << Fours;
}
Count of fours: 2

## Summary

In this lesson, we explored the counting algorithms that are part of the C++20 std::ranges library, and available by including the <algorithm>Â header.

### Key Takeaways

• Understanding of std::ranges::count() for counting specific elements in a range.
• Use of std::ranges::count_if() to count elements that meet a predicate condition.
• Application of std::ranges::any_of(), none_of(), and all_of() for conditional checks across elements.
• Insight into the performance benefits of using specific algorithms like any_of() over alternatives like count_if() in certain scenarios.
• Using predicates in customizing the behavior of counting algorithms.
• How to use member functions as predicates for more complex conditions.
• The role of projection functions in transforming elements before applying counting algorithms.
• Review of using iterator-sentinel pairs for defining custom ranges.

Next Lesson

### Minimum and Maximum Algorithms

An introduction to the seven minimum and maximum algorithms in the C++ standard library: clamp(), min(), min_element(), max(), max_element(), minmax(), and minmax_element().
New: AI-Powered AssistanceAI Assistance

### Questions and HelpNeed Help?

Get instant help using our free AI assistant, powered by state-of-the-art language models.

Updated
Lesson Contents

### Counting Algorithms

An introduction to the 5 main counting algorithms in the C++ standard library: count(), count_if(), any_of(), none_of(), and all_of()

This lesson is part of theÂ course:

### Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, Unlimited Access

###### Counting Algorithms

An introduction to the 5 main counting algorithms in the C++ standard library: count(), count_if(), any_of(), none_of(), and all_of()

This lesson is part of the course:

## Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

### This course includes:

• 124 Lessons
• 550+ Code Samples
• 96% Positive Reviews
• Regularly Updated
• Help and FAQ
Next Lesson

### Minimum and Maximum Algorithms

An introduction to the seven minimum and maximum algorithms in the C++ standard library: clamp(), min(), min_element(), max(), max_element(), minmax(), and minmax_element().