You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于atomic_fetch_max编译失败及参数类型设计的技术咨询

关于atomic_fetch_max编译失败及参数类型设计的技术咨询

在代码评审时你收到的这个atomic_fetch_max版本编译失败,咱们先拆解原因,再聊参数类型的设计思路。

一、为什么建议的atomic_fetch_max会编译失败?

最可能的原因是编译器的C标准版本低于C20,或者你的代码没有启用C++20及以上的编译选项。

你看建议版本里的这行代码:

auto prev = *obj;

std::atomic<T>operator*()是C20才新增的特性,在C17及更早的标准中,std::atomic并没有这个重载运算符。如果用旧标准编译,编译器根本找不到这个操作符,自然会报错——虽然编译器输出可能堆了一堆模板展开的冗余信息,显得很乱,但核心错误就是找不到operator*

解决方法很简单,把*obj替换成原子类型的load()成员函数即可,这是C++11以来就支持的标准写法:

auto prev = obj->load();

另外可以确认下模板参数Tstd::atomic支持的类型(必须是可平凡复制的类型,比如基本类型、指针等),不过你的原函数update_max能编译,说明T是合法的,这个大概率不是问题。

二、为什么用typename std::atomic<T>::value_type arg而不是TT const&

咱们分两点来解释:

1. 用std::atomic<T>::value_type而非T的原因

其实从定义上来说,std::atomic<T>::value_type就是T的别名(标准库中std::atomic的定义里会typedef T value_type;),这么写主要是:

  • 遵循标准库惯例:你提到的原子最大值/最小值提案,其函数签名完全沿用了标准库原子操作(比如atomic_fetch_add)的风格,这些标准函数都用typename std::atomic<T>::value_type作为参数类型,目的是和原子类型的内部值类型严格对齐。
  • 兼容潜在特化场景:虽然目前std::atomic的特化中value_type都是T,但如果未来有特殊的平台扩展原子类型特化,用value_type可以保证参数类型和原子内部存储的类型完全一致,避免类型不匹配的风险。

2. 不用T const&而用传值的原因

原子操作的参数通常倾向于传值而非传引用,原因有这几个:

  • 原子操作的目标类型一般是轻量类型(比如int、long、指针),传值的开销比传引用更小(不需要间接寻址)。
  • 避免生命周期风险:如果用T const&,你得确保传入的引用在整个原子操作循环期间是有效的,但多线程场景下,引用指向的对象可能被其他线程修改甚至销毁,传值可以拿到一个独立的副本,更安全。
  • 契合标准API设计:std::atomiccompare_exchange_weak函数的desired参数就是传值的,用传值的arg可以直接和这个参数匹配,额外拷贝的成本几乎可以忽略。

备注:内容来源于stack exchange,提问作者Damir Tenishev

火山引擎 最新活动