引用 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
的纯右值。存在从 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
,或将条件表达式替换为if
声明将解决问题…
我有一个 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
的纯右值。存在从 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
,或将条件表达式替换为if
声明将解决问题…