引用std :: atomic <bool>

时间:2019-04-08 02:12:29

标签: c++ visual-c++ atomic

我有一个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()函数上收到以下错误。

  

错误C2280'std :: atomic :: atomic(const std :: atomic&)':   试图引用已删除的功能

我知道发生这种情况是因为删除了原子的副本构造函数。但是我遵循this answer并定义了副本构造函数。 我不知道为什么错误仍然会出现。 我也尝试过:

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:

经过更多的故障排除后,我发现问题可能是返回类型。 如果是三元条件exp1 ? exp2 : exp3,则返回类型为exp2的类型(如here所述)。 因此,在这种情况下,B :: getBool()的返回类型变为atomic_bool,而不是atomic_bool。 当我将static_cast的代码添加到以下代码时,我不再收到错误。

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

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

1 个答案:

答案 0 :(得分:1)

您的条件表达式

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

不应编译。但是,其原因与std::atomic<bool>的副本构造函数无关。此条件在其间切换的两个表达式分别是,第一个是类类型std::atomic<bool>的左值,第二个是非类类型bool的prvalue。存在从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,或将条件表达式替换为{{ 1}}语句将解决此问题……