Step 5 of 6
Constraining templates with concepts
An unconstrained template accepts any type and fails deep inside its body with a wall of errors. A concept states the requirements up front, so a wrong type gets one clear error at the call site:
template <typename T>
concept Shape = requires(const T& s) {
{ s.area() } -> std::convertible_to<double>;
{ s.name() } -> std::convertible_to<std::string>;
};
template <Shape S>
void print(const S& s);
A requires expression lists operations that must compile, and optionally what they must return. This gives you static polymorphism: shapes that share no base class and have no virtual functions still work, with zero runtime cost.
Your turn: write the Shape concept above and template <Shape S> double total_area(const std::vector<S>& shapes).
Previous: Writing your own trait Next: Challenge: compile-time computation