// 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;
}