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

C++如何对包含std::atomic成员的结构体执行聚合初始化?

问题根因

你遇到的编译错误是C++14及更早标准下聚合初始化规则与std::atomic类型特性冲突导致的:

  1. C++14标准中,聚合初始化通过花括号传值初始化成员时,会先构造一个和成员同类型的临时对象,再通过拷贝/移动构造的方式将临时对象初始化到聚合体的成员内存位置。
  2. std::atomic系列类型从标准设计上就删除了拷贝、移动构造函数——原子对象的拷贝操作本身无法保证原子性,因此标准直接禁用了该语义。
  3. 你提到的MSVC可正常编译是历史原因:MSVC早期版本对聚合初始化做了非标准扩展,跳过了临时对象拷贝的步骤直接原地构造成员,属于实现层面的特殊行为,并不符合C++14的标准要求。
    你看到的报错信息use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’,就是因为编译器尝试调用被删除的atomic拷贝构造函数来初始化结构体成员导致的。
正确初始化方案

根据你使用的C++标准版本,选择对应合法写法即可:

C++17及以上标准

直接使用你示例中的写法即可正常编译:

Foo f{1};

C17标准引入了强制拷贝消除规则,该场景下编译器不会生成临时的atomic对象,也不会调用拷贝构造,而是直接用传入的1在结构体成员的内存位置原地构造std::atomic_int对象,完全符合标准语义,GCC、Clang等编译器在C17及以上配置下都可以正常编译该代码。

C11/C14 兼容标准写法

如果需要兼容C++11/14旧标准,有两种无未定义行为的可行方案:

  • 方案1:为结构体添加自定义构造函数,在构造函数初始化列表中直接初始化atomic成员,绕开聚合初始化的拷贝逻辑
    #include <atomic>
    
    struct Foo
    {
        std::atomic_int atomic;
        constexpr Foo(int init_val) : atomic(init_val) {}
    };
    
    int main() {
        Foo f{1}; // 合法,直接调用自定义构造函数初始化成员
    }
    
  • 方案2:先对结构体做值初始化,再通过atomic的store接口显式写入目标值。注意该方式的初始化操作不具备原子性,仅可用于无其他线程并发访问该对象的场景(比如程序启动阶段的单线程初始化流程)
    #include <atomic>
    
    struct Foo
    {
        std::atomic_int atomic;
    };
    
    int main() {
        Foo f{}; // 成员atomic被默认初始化为0
        f.atomic.store(1, std::memory_order_relaxed); // 显式写入目标值
    }
    
注意事项

所有std::atomic类型的拷贝、移动构造、拷贝赋值、移动赋值运算符都是标准明确删除的,不要尝试通过拷贝另一个atomic对象的方式完成初始化,这类操作本身就不符合原子类型的设计语义,会直接触发编译错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 04:12:56