Concepts
- C++ course
- Advanced
- Lesson 4/83
- 5 min
Learn template constraints with C++20 concepts.
Concepts
Concepts (C++20) are type constraints placed on template parameters. You write template <typename T> requires std::integral<T> auto twice(T x). When the constraint fails the compiler gives a clear error message.
Concepts replace verbose SFINAE error messages with a readable tool. The standard library ships ready concepts like std::integral, std::floating_point and std::convertible_to. A constraint is given with a requires clause or the short form template <std::integral T>.
When the constraint fails
A concept is checked at compile time. If the twice template carries std::integral<T>, calling twice(std::string{...}) fails to compile. The error says 'string does not satisfy integral'; no deep SFINAE stack appears.
Concepts also support expression requirements written as requires (T a, T b) { a + b; }. This tests at compile time that type T supports the + operator.
Practice Constrained twice template with concepts
Write template <typename T> requires std::integral<T> auto twice(T x) with body return x * 2;. In main call twice(6) and print the result via std::cout.
Starter code
#include <iostream>
#include <concepts>
// Write the twice template with requires
int main() {
// Call twice(6) and print
return 0;
}Sample solution
#include <iostream>
#include <concepts>
template <typename T>
requires std::integral<T>
auto twice(T x) {
return x * 2;
}
int main() {
std::cout << twice(6);
return 0;
}Expected output
12
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match each concept to its role
| Term | Meaning |
|---|---|
std::integral<T> |
Integer constraint |
requires std::integral<T> |
Requires clause |
template <std::integral T> |
Short form |
std::floating_point<T> |
Floating constraint |
2 Complete the requires clause
template <typename T> ____ std::integral<T> auto twice(T x) { return x * 2; }
template <typename T> requires std::integral<T> auto twice(T x) { return x * 2; }
Explanation: requires starts the constraint clause.
3 Which line is NOT a concept-constrained template?
- template <std::integral T>
- template <typename T> requires std::integral<T>
- requires std::integral<T>
- template <typename T> Correct answer
Explanation: This line has no concept constraint.