试图引用已删除的函数(复制 c'tor)

Attempting to reference a deleted function (copy c'tor)

我从 Anthony Williams 那里得到了这个 spinlock 的例子,但它有问题(或者我度过了漫长的一天)。

#include <atomic>
class spinlock 
{
    std::atomic_flag flag;
public:
    spinlock() : flag(ATOMIC_FLAG_INIT) {}
    void lock() {
        while (flag.test_and_set(std::memory_order_acquire));
    }
    void unlock(){
        flag.clear(std::memory_order_release);
    }
};

spinlock sl;
void f() 
{
    std::lock_guard lc(sl);
}

int main()
{
    f();
}

所以这足以让std::lock_guard获得它,但我有一个编译错误。

错误 C2280:'std::atomic_flag::atomic_flag(const std::atomic_flag &)':试图引用已删除的函数

老实说,我不明白 spinlock() : flag(ATOMIC_FLAG_INIT) {} 是如何调用复制构造函数的。
我使用 VS2022C++20 标准,ATOMIC_FLAG_INIT 定义如下:

#define ATOMIC_FLAG_INIT \
    {}

是这本书的例子坏了,还是我穿错了?

ATOMIC_FLAG_INIT只能这样使用:

std::atomic_flag v = ATOMIC_FLAG_INIT;

未指定如果

flag(ATOMIC_FLAG_INIT)

会起作用。如果 visual studio 将 ATOMIC_FLAG_INIT 定义为 {} 那么您的代码可能最终会创建一个带有 {}std::atomic_flag 然后调用 flag 的已删除复制构造函数.

如果您使用的是 c++20,您可以简单地删除 flag 初始化程序,因为 std::atomic_flag 的默认构造函数现在初始化为 false.

如果没有 c++20,我认为根据标准执行此操作的唯一方法是使用内联初始化程序:

class spinlock 
{
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
    void lock() {
        while (flag.test_and_set(std::memory_order_acquire));
    }
    void unlock(){
        flag.clear(std::memory_order_release);
    }
};