C++20 introduced two revolutionary pillars that modernized template metaprogramming and algorithmic data processing: Concepts (type constraints) and Ranges (composable functional pipelines).
#include <iostream>
#include <concepts>
// Define a Concept restricting T to numeric types only
template <typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
// Function constrained by the Numeric concept
Numeric auto calculateAverage(Numeric auto a, Numeric auto b) {
return (a + b) / 2.0;
}
int main() {
std::cout << calculateAverage(10, 20) << "\n"; // OK: 15.0
std::cout << calculateAverage(4.5, 9.5) << "\n"; // OK: 7.0
// calculateAverage("Hello", "World"); // COMPILE ERROR! String does NOT satisfy Numeric!
return 0;
}
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Lazy pipeline: Filter even numbers, square them, take first 3
auto view = numbers
| std::views::filter([](int n) { return n % 2 == 0; })
| std::views::transform([](int n) { return n * n; })
| std::views::take(3);
std::cout << "Transformed: ";
for (int val : view) {
std::cout << val << " "; // Prints: 4 (2^2), 16 (4^2), 36 (6^2)
}
std::cout << "\n";
return 0;
}
Boost your C++ proficiency by studying these closely connected core modules:
How concepts constrain generic templates.
Traditional algorithms vs modern range pipelines.
The next big pillar of C++20.