引用 std::atomic<bool> 的已删除函数错误

Referencing a deleted function error for std::atomic<bool>

我有一个 std:atomic_bool,我在我的代码中定义为:

class A
{
public:
A();
A(const A&);
~A();

std::atomic_bool isTrue;
}

A:A()
{
isTrue= false;
}

A::A(const A&) : isTrue(false)
{}

然后我执行以下操作:

class B
{
A aObj;

public:
bool getBool()
{
return GetNumberOfUsers() > 1 ? aObj.isTrue : true;
}

我在 getBool() 函数中遇到以下错误。

Error C2280 'std::atomic::atomic(const std::atomic &)': attempting to reference a deleted function

我知道这是因为原子的复制构造函数被删除了。但是我已经按照 定义了复制构造函数。 我不知道为什么错误仍然出现。 我也试过:

class A
    {
    ...  
    A(const A&) = delete;

但是还是报错。

编辑: 经过一些故障排除后,我遇到了一个奇怪的行为。 我发现,如果我在 B::getBool() 中按以下条件更改我的三元组,我将不会收到错误。

bool getBool()
{
   // return GetNumberOfUsers() > 1 ? aObj.isTrue : true;
   if (GetNumberOfUsers() > 1)
        return aObj.isTrue ;
   else
        return true;
}

现在更令人困惑了。

编辑 2:

经过更多的故障排除后,我发现问题可能出在 return 类型上。 在三元 if 条件 exp1 ? exp2 : exp3 中,return 类型是 exp2 的类型(如 here 所述)。 所以在这种情况下,B::getBool() 的 return 类型变成了 atomic_bool,而不是原子的。 当我在下面添加 static_cast 代码时,我不再收到错误。

bool getBool()
{
        return GetNumberOfUsers() > 1 ? static_cast<bool>(aObj.isTrue) : true;
}

但是我仍然不知道为什么这会抛出复制构造函数错误。 谢谢。

你条件表达式

GetNumberOfUsers() > 1 ? aObj.isTrue : true;

不应该编译。然而,其原因与 std::atomic<bool> 的复制构造函数无关。此条件切换之间的两个表达式首先是 class 类型 std::atomic<bool> 的左值,其次是非 class 类型 bool 的纯右值。存在从 boolstd::atomic<bool> 的隐式转换序列。还存在从 std::atomic<bool>bool 的隐式转换序列。因此,根据 [expr.cond]/4,该程序应该是病式的。

我相信 MSVC 显然试图使此表达式导致 std::atomic<bool> 的事实一定是 MSVC 中的错误。请注意,当前版本的 MSVC 在切换到一致性模式(通过 /permissive- 选项;如果可以的话,每个人都应该使用它)时,将正确诊断问题,与其他编译器一致。 live demo here

正如您自己所学,使用 aObj.load() 获取其 bool 值,将 aObj.isTrue 显式转换为 bool,或将条件表达式替换为if 声明将解决问题…