我有一个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;
}
但是我仍然不知道为什么这会引发复制构造函数错误。 谢谢。
答案 0 :(得分:1)
您的条件表达式
GetNumberOfUsers() > 1 ? aObj.isTrue : true;
不应编译。但是,其原因与std::atomic<bool>
的副本构造函数无关。此条件在其间切换的两个表达式分别是,第一个是类类型std::atomic<bool>
的左值,第二个是非类类型bool
的prvalue。存在从bool
到std::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}}语句将解决此问题……