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

为何C++17中std::make_shared使用非inline静态const成员会出现链接错误

问题原因解析

为什么报错发生在链接期而非编译期

  • 你定义的SomeType::MIN、SomeType::MAX属于类内初始化的static const整型成员,按照C++标准,这类成员如果只是做值读取的常量折叠,编译期不需要实体定义即可使用。
  • 但你在调用std::make_shared<Range>()时,参数会被绑定到std::make_shared的转发引用形参上,这属于ODR使用(One Definition Rule,单一定义规则):即需要该变量有唯一的内存实体、可以取地址的使用场景。这种情况下标准要求必须在类外额外提供该静态成员的全局定义,否则会缺少符号。
  • 编译期每个编译单元只会检查语法合法性,编译器默认假设该静态成员的定义会在其他编译单元提供,因此不会抛出编译错误。直到链接阶段需要合并所有编译单元的符号时,才会发现找不到SomeType::MIN、SomeType::MAX的实体定义,因此抛出链接错误。
  • 至于MSVC可以正常编译的原因,是MSVC默认开启了兼容扩展,对类内初始化的static const整型成员的ODR使用场景自动生成了符号定义,不遵循严格的C++标准;而GCC默认遵循标准要求,因此会抛出链接错误。

为什么添加inline关键字可以解决问题

C++17标准新增了inline静态成员变量的规则:

  • 类内初始化的inline静态成员变量,不需要再额外在类外提供全局定义,编译器会自动保证所有用到该成员的编译单元都生成对应的弱符号,链接时只会保留一份唯一的实体,既不会出现重复定义错误,也不会出现符号找不到的错误。
  • 你给两个static const int成员添加inline修饰后,完全符合C++17的inline静态成员规则,因此不需要额外写类外定义即可正常链接通过。
  • 如果你不使用inline,也可以在类外添加两行定义来解决问题:
const int SomeType::MIN;
const int SomeType::MAX;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:18:02