Concepts 是 C++20 将模板隐式契约显性化的核心特性,支持 requires 约束、命名 concept 定义、auto 参数推导及类模板特化,显著提升接口清晰度、错误提示质量与代码可维护性。

Concepts 是 C++20 引入的核心特性,它让模板参数的约束从“运行时失败”或“编译器报一长串错误”的黑盒状态,变成**可读、可复用、可推导的显式契约**。用好 Concepts,不是给模板加个装饰,而是从根本上提升接口清晰度、错误提示质量和代码可维护性。
最轻量的用法是直接在函数模板或类模板声明处使用 requires 子句,检查类型是否满足一组条件:
+ 和 ==,且结果可转为 bool:template
requires std::is_arithmetic_v
requires(T a, T b) { { a + b } -> std::same_as
T add_if_equal(T x, T y) { return x == y ? x + y : x; }
这种写法适合一次性、小范围约束,无需提前定义 concept 名称,但可读性略低,复用性差。
把常见约束封装成具名 concept,就像定义接口一样清晰:
立即学习“C++免费学习笔记(深入)”;
template
concept Addable = requires(T a, T b) {
{ a + b } -> std::same_as
};
template
concept EqualityComparable = requires(T a, T b) {
{ a == b } -> std::convertible_to
};
template
T sum(T a, T b) { return a + b; }
template
T combine_if_equal(T a, T b, U x, U y) {
return (x == y) ? a + b : a;
}
命名 concept 可组合(如 concept IntegralAddable = std::integral<t> && Addable<t></t></t>),便于文档化、测试和团队协作。
C++20 允许在函数参数中直接使用 concept 名称替代 auto,这比传统模板更简洁,又比裸 auto 更严格:
void process(Addable auto x, Addable auto y) { /* ... */ }
// 调用时:
process(3, 5); // ✅ int 满足 Addable
process(3.14, 2.71); // ✅ double 满足 Addable
process("a", "b"); // ❌ 编译失败,明确提示:type 'const char*' does not satisfy 'Addable'
相比 template<typename t> void process(T x, T y)</typename>,它省去模板声明,避免意外接受不合法类型(比如传两个不同算术类型导致隐式转换歧义),错误信息也直指 concept 名称而非底层 SFINAE 细节。
Concept 不仅用于函数,还能精准控制类模板的可用性,甚至参与偏特化选择:
template
class Container { /* 通用实现 */ };
template
class Container
template<:integral t>
class Container
注意:多个特化必须满足**偏序规则**(即一个 concept 必须严格强于另一个,如 std::integral 是 EqualityComparable 的子集),否则编译器会报歧义。合理设计 concept 层级,能让特化逻辑更健壮。
Concepts 不是语法糖,它是把模板的“隐式契约”显性化、结构化的过程。写模板前先想清楚“这个参数到底要能做什么”,把它写成 concept,后续所有使用都自动获得类型安全和清晰反馈。不复杂但容易忽略。
以上就是C++20 Concepts用法_现代C++ Concepts如何提升模板编程安全的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号