C++
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C++
-
Section 4: Memory Management
-
Section 5: Templates and Generic Programming
-
Section 6: The Standard Template Library
-
Section 7: Modern C++ Features
-
Section 8: Error Handling
-
Section 9: Multithreading
-
Section 10: Operator Overloading and Type Conversion
-
Section 11: Advanced Topics
-
Section 12: Tooling and Build Systems
-
Section 13: Design Patterns in C++
-
Section 14: Interfacing with C and Systems Programming
-
Section 15: Networking and IPC Basics
-
Section 16: Graphics and Game Programming Basics
-
Section 17: The Boost Libraries
-
Section 18: Data Structures and Algorithms in C++
-
Section 19: Practical Projects
-
Section 20: More Concurrency Patterns
-
Section 21: More OOP and Design Practice
-
Section 22: File I/O and Streams
-
Section 23: More Standard Library
-
Section 24: Practice Exercises
-
Section 25: Interview and Algorithm Practice
-
Section 26: Compiler and Language Internals
-
Section 27: GUI and Application Frameworks Overview
-
Section 28: Testing and Quality Practices
-
Section 29: Numerics Library
-
Section 30: Concepts Library (C++20)
-
Section 31: Ranges Library (C++20) In Depth
-
Section 32: More Utility Library
71: Algorithms Library: accumulate and count_if
I want to show you a snippet of code that looks perfectly fine at first glance, but it produces a result that will make you pull your hair out if you don't know how std::accumulate actually works under the hood. Imagine you're writing a small module to calculate the total cost of items in a digital shopping cart.
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<double> prices = {10.99, 5.50, 20.25, 3.75};
// We want the total sum of prices
double total = std::accumulate(prices.begin(), prices.end(), 0);
std::cout < "Total: " < total < std::endl;
return 0;
}
If you run this, you'll expect to see 40.49. Instead, you get 40. The decimals are just... gone. You might check your std::cout settings or double-check the vector values, but the logic seems airtight. So, what's happening?
The Integer Truncation Trap
The culprit is the third argument in std::accumulate: the initial value. In the code above, I passed 0. In C++, 0 is an int.
Here is the subtle part: std::accumulate uses the type of that initial value to determine the type of the internal accumulator. Because I provided an int, the function performs all its additions using integer arithmetic. Every time it adds a double from the vector to the running total, that double is cast to an int, stripping away the fractional part before the addition even happens. By the time the result is assigned to the double total variable, the precision is already lost.
Matching the Initial Value Type
To fix this, you have to be explicit about the type you want for the accumulation. If you're working with doubles, your starting value must be a double.
// Fix: Change 0 to 0.0
double total = std::accumulate(prices.begin(), prices.end(), 0.0);
By passing 0.0, you tell the compiler to use a double for the summation. Now the precision is preserved, and you get the 40.49 you were expecting. It's a tiny detail, but it's one of those "C++ moments" that catches even experienced devs when they're moving quickly.
Counting with Predicates
Now, usually, when we're summing things up, we also need to know how many items met a specific condition. You could write a for loop with an if statement and a counter, but that's boilerplate we don't need. That's where std::count_if comes in.
Unlike accumulate, which reduces a range to a single value via addition (by default), count_if takes a "predicate"—a function or lambda that returns true or false—and returns the number of elements for which that predicate was true.
Let's say we want to find out how many items in our cart are "premium" items (costing more than $10.00):
#include <algorithm> // Required for count_if
// ... inside main ...
int premium_count = std::count_if(prices.begin(), prices.end(), [](double p) {
return p > 10.00;
});
std::cout < "Premium items: " < premium_count < std::endl;
I prefer count_if over a manual loop because it communicates intent. When another engineer sees count_if, they immediately know you're filtering and counting, rather than having to parse the logic inside a loop body to figure out what your goal was.
📋 Practical Task
Server Response Time Analyzer
You are tasked with analyzing a list of server response times (in milliseconds). You need to write a program that processes a std::vector<double> of response times to determine the system's health.
Requirements:
- Create a vector containing these values:
{120.5, 450.2, 80.1, 1100.7, 300.3, 1500.2, 95.4}. - Use
std::accumulateto calculate the total time spent on all requests. (Ensure you don't fall into the truncation trap!) - Use
std::count_ifto count how many requests were "slow"—defined as any response time greater than 500.0ms. - Calculate the average response time by dividing the total time by the number of elements in the vector.
- Print the total time, the number of slow requests, and the average response time to the console.
There are no comments for now.