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
相关产品推荐
相关产品推荐

