C/C++ Arena

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