Search⌘ K
AI Features

Solution: Generic Data Aggregator

Understand how to create a generic data aggregator in C++ by using templates and concepts. Learn to define type constraints with the Numeric concept, handle specialization for string types, and ensure type safety with static assertions. This lesson helps you master generic programming techniques essential for writing reusable and type-safe components.

We'll cover the following...
C++ 23
// Caption: Corrected Aggregator using static_assert to allow string specialization
#include <iostream>
#include <string>
#include <concepts>
// Define the 'Numeric' concept
template <typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
// CHANGE 1: Use 'typename T' instead of 'Numeric T' here.
// This allows the compiler to consider types that don't fit 'Numeric'
// (like std::string) so it can check if a specialization exists for them
template <typename T>
class Aggregator {
// CHANGE 2: Enforce the constraint INSIDE the class
// This stops 'bool' or other invalid types from compiling,
// but allows 'std::string' to bypass this check because
// std::string uses the specialization below (which doesn't have this line)
static_assert(Numeric<T>, "Aggregator can only be used with Numeric types or std::string.");
private:
T total{0};
public:
void add(T value) {
total += value;
}
T getResult() const {
return total;
}
};
// Template specialization for std::string
// The compiler uses THIS implementation for strings, completely ignoring
// the primary class above (and its static_assert)
template <>
class Aggregator<std::string> {
private:
std::string buffer;
public:
void add(const std::string& value) {
if (!buffer.empty()) {
buffer += " ";
}
buffer += value;
}
std::string getResult() const {
return buffer;
}
};
int main() {
Aggregator<int> scoreTracker;
scoreTracker.add(100);
scoreTracker.add(50);
std::cout << "Total Score: " << scoreTracker.getResult() << "\n";
Aggregator<double> fuelTracker;
fuelTracker.add(45.5);
fuelTracker.add(10.2);
std::cout << "Total Fuel: " << fuelTracker.getResult() << "\n";
Aggregator<std::string> logSystem;
logSystem.add("System started.");
logSystem.add("Driver detected.");
std::cout << "Logs: " << logSystem.getResult() << "\n";
return 0;
}
...