You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20中requires表达式为何直接触发编译错误而非返回false

核心差异原因

你遇到的行为是C++标准明确规定的,区别的核心是requires表达式中的检查是否依赖模板参数:

  • 你在非模板的main函数里直接写requires表达式时,n += bad的两个操作数类型是固定的int和Bad,完全不依赖模板参数,编译器可以立刻判定不存在合法的operator+=重载,这种「和模板参数无关的明确非良构构造」属于硬编译错误,不会让requires表达式返回false。
  • 当你把逻辑写到模板约束中时,表达式的操作数属于待决类型(依赖模板参数),编译器在模板定义阶段不会做强制语义检查,等到实例化时如果找不到匹配的运算符,才会让requires表达式返回false,属于SFINAE友好的失败,符合你的预期。

requires表达式直接触发编译错误的场景

只要同时满足以下两个条件,requires就会直接抛出编译错误,而不会返回false:

  • requires表达式处于非模板语境,或者其中的检查内容完全不依赖任何模板参数
  • 检查的表达式在当前语境下明确非良构,不存在任何合法匹配的可能

实现你预期的写法

如果要在非模板语境下也让requires正常返回false,可以把检查逻辑封装到辅助模板变量里:

struct Bad {};

template<typename T, typename U>
constexpr bool has_add_assign = requires(T a, U b) { a += b; };

int main() {
    // 只会触发static_assert失败,不会提前报运算符不存在的错误
    static_assert(has_add_assign<int, Bad>);
}

内容的提问来源于stack exchange,提问作者sudo rm -rf slash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:06:04