Concepts 是 C++20 对 SFINAE 的演进而非替代,通过显式命名、清晰错误信息、声明处约束检查和语法封装,解决了 SFINAE 写法绕、读晦涩、错难懂、不可复用等痛点,但底层仍依赖 SFINAE。

Concepts 是 C++20 引入的正式语法机制,用来直接表达模板参数的约束条件;而 SFINAE(Substitution Failure Is Not An Error)是 C++11/14 时期“曲线救国”式实现模板约束的技术手段——Concepts 本质上是对 SFINAE 约束逻辑的语法封装与语义升华,不是替代,而是演进。
Concepts 解决了 SFINAE 的哪些痛点
SFINAE 虽然可行,但写起来绕、读起来晦涩、错起来难懂:
- 约束逻辑藏在函数重载或 enable_if 的模板参数里,和语义意图脱节;
- 错误信息中充斥着冗长的 substitution failure 堆栈,真正的问题(比如 “T 没有 operator
- 无法对概念本身命名复用,相同约束(如 “可比较”、“可迭代”)需重复写 enable_if + traits;
- 不支持 concept 检查点提前终止:SFINAE 只在实例化时才触发淘汰,而 Concepts 可在模板声明处就拒绝不满足要求的实参。
SFINAE 仍是 Concepts 的底层基础
Concepts 并没有废除 SFINAE,而是构建在其之上:
- 每个 concept 的定义(如
requires (T t) { t.begin(); t.end(); })在编译器内部仍会触发表达式替换,失败时仍走 SFINAE 规则; - 使用 concept 限定的函数模板(如
template<iterable i> void f(I&)</iterable>)在重载解析阶段,不满足 concept 的类型会被 SFINAE 排除; - 你依然可以在 concept 内部使用
std::is_integral_v<t></t>等 type traits —— 这些 traits 本身也依赖 SFINAE 实现。
从 SFINAE 到 Concepts:一个对比示例
目标:只接受支持 begin()/end() 且元素可打印的容器类型。
立即学习“C++免费学习笔记(深入)”;
● SFINAE 写法(C++14):
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~