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

使用requires子句禁用非法拷贝构造函数失效问题

代码在Clang编译通过但GCC失败的原因分析

先看你提供的代码:

#include <cstdint>
template <std::size_t N>
struct foo
{
    foo(foo<0> other) requires (N != 0) {}
};
int main() {}

问题核心在于C++标准对类模板成员声明的检查规则,以及GCC和Clang的实现差异:

  • 当实例化foo<0>时,编译器会扫描类内所有成员的声明——即使某个成员函数的requires约束不满足,编译器仍需检查该成员声明本身的合法性,而非直接忽略整个函数。
  • 你的构造函数参数是foo<0> other(按值传递),而按值传递参数要求对应的类型是完全类型(编译器需要知道对象大小才能分配栈空间)。但此时foo<0>正处于类模板实例化过程中,类定义还未完成,属于不完全类型。
  • Clang的实现逻辑是:既然该构造函数的约束N!=0在N=0时不成立,这个函数永远不会被实例化,因此跳过了对参数类型完全性的严格检查;而GCC严格遵循标准中“类模板成员声明必须合法”的要求,即使约束不满足,也会检查声明的类型合法性,发现foo<0>作为不完全类型用于按值传参,因此抛出错误。

可以做个验证:如果把参数改成引用类型foo<0>& other,引用不需要类型是完全类型,此时GCC也能正常编译通过,这就印证了问题的根源是按值传参对完全类型的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:48:13