C++ Concepts and Constraints | Type Requirements in C++20
이 글의 핵심
Practical guide to C++ concepts: syntax, standard library concepts, and migration from SFINAE.
What are concepts?
Concepts give explicit constraints on template parameters.
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template<Addable T>
T add(T a, T b) {
return a + b;
}
Basic usage
#include <concepts>
template<std::integral T>
T square(T value) {
return value * value;
}
Standard concepts (overview)
#include <concepts>
// integral<T>, floating_point<T>, equality_comparable<T>, etc.
Custom concepts
template<typename T>
concept Container = requires(T t) {
typename T::value_type;
{ t.begin() } -> std::same_as<typename T::iterator>;
{ t.end() } -> std::same_as<typename T::iterator>;
{ t.size() } -> std::convertible_to<std::size_t>;
};
template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
template<typename T>
concept Printable = requires(std::ostream& os, T t) {
{ os << t } -> std::convertible_to<std::ostream&>;
};
Generic function example
template<Numeric T>
T average(const std::vector<T>& values) {
if (values.empty()) return T{};
T sum{};
for (const auto& v : values) sum += v;
return sum / static_cast<T>(values.size());
}
requires clauses
template<typename T>
requires std::integral<T>
T square(T value) { return value * value; }
template<typename T>
requires requires(T t) {
{ t.size() } -> std::convertible_to<std::size_t>;
}
std::size_t getSize(const T& c) { return c.size(); }
Concepts vs SFINAE
Concepts typically replace dense enable_if with readable requirements on the template line.
FAQ
See the Korean original for extended examples (sorting, iterators, hashable types). Behavior and code are unchanged.
Related posts
- Custom concepts series
- Template lambda
Keywords
C++, concepts, constraints, requires, C++20