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

C++中`requires A`与`requires (A)`是否等价?标准合规性问询

关于C++模板requires子句括号导致的匹配问题

问题背景

该讨论最初发起于llvm/llvm-project#60377。反复阅读C++标准的temp.constr.atomic和temp.constr.normal章节后,因英文水平有限,对该问题愈发困惑。

为了让clang-format正确格式化requires子句而添加括号后,修改代码风格时出现意外错误,示例代码如下:

#include <concepts>

template <typename T>
  requires std::integral<T>
struct [[nodiscard]] Widget;

template <typename T>
  requires(std::integral<T>)  // error: Requires clause differs
struct [[nodiscard]] Widget {
  T value;
};

[[nodiscard]] auto main() -> int {
  Widget<int> widget{1};
  return widget.value;
}

不同编译器测试结果:

  • x86_64 clang(最新版):报错
  • x86_64 gcc(最新版):编译通过
  • x64 msvc v19.latest:报错

请问根据C++标准,clang/msvc和gcc中哪一个的行为符合预期?


结论与标准依据

根据C++标准,clang和MSVC的行为符合预期,gcc的行为不符合标准。

C++标准要求,模板的声明与定义的约束必须是等价的才能匹配。对于原子约束的等价性判断,语法结构是重要依据:带括号的(std::integral<T>)和不带括号的std::integral<T>属于不同的表达式结构,因此对应的原子约束并不等价。

具体来说,requires(std::integral<T>)中的括号使表达式成为括号表达式,而requires std::integral<T>是简单的概念实例化表达式。按照标准中约束等价性的规则,这两个约束不被视为等价,因此模板声明与定义的约束不匹配,编译器应当报错。


内容的提问来源于stack exchange,提问作者FeignClaims

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:23:55