首页 > 解决方案 > c++中的原子向量:msvc vs gcc

问题描述

我在 Linux 上开发了一些代码,它使用了一个std::vector变量std::atomic——我使用的每个线程一个变量,对于一些不同的计算,它可能设置为不同的数字。在简单的形式中,它看起来像:

编辑:还包括重置功能:

class threadsafe_vals{
    std::vector<std::atomic<int> > vals;
public:
    threadsafe_vals(int _n){
        vals = std::vector<std::atomic<int> >(_n);
        for (auto &x:vals){
            x=0;
        }
    }
    void reset(int _i){
        vals =std::vector<std::atomic<int> >(n);
        for (auto &x:vals){
            x=0;
        }
    }
    int get(int _i){ return vals[_i];}
    void set(int _i,in _val){ vals[_i] = _val;}
};

我知道std::atomics 没有复制构造函数,所以我确保我从未使用过诸如erase push_backetc. 之类的东西,而是简单地将向量视为一个固定数组,直到我重置整个东西。每当我重置向量时,我总是使用该行vals = std::vector<std::atomic<int> >(n)来避免使用复制构造函数,而是破坏现有的原子然后简单地初始化(我认为)。在操作期间代码不需要是线程安全的reset(int n)

无论如何,对于使用 Clang 的 Linuxgcc和使用 Clang 的 Mac,这一切都有效。

然后,我尝试将我的代码移植到 MSVC 下的 Windows,但它不会编译。

我现在得到编译器错误

std::atomic<int>::atomic(const std::atomic<int> &): attempting to reference a deleted function

在文件中xmemory()

看起来它在抱怨它必须使用atomics我正在使用的复制构造函数。

现在:gcc 和 clang 都足够聪明,可以发现我实际上并没有使用复制构造函数并编译了我的代码,所以我假设这是一个 Microsoft c++ 实现的东西。

但问题仍然存在:

  1. 为什么 MSVC 认为我在这里调用了复制构造函数?

  2. 更重要的是,我怎样才能获得所需的效果,即我可以拥有一个原子向量,而无需根据 MSVC(或任何其他方法)调用复制构造函数,类似于我的原始代码,以可移植的方式?

我尝试搜索一些类似的问题,但答案似乎无处不在,有些人说原子向量根本不可能。但这是错误的,至少根据 c++ 标准的 gcc 和 clang 解释是错误的。

标签: c++c++11vectorvisual-c++atomic

解决方案


推荐阅读