我想使用std::atomic_int
变量。在我的代码中,我有:
#include <atomic>
std::atomic_int stop = 0;
int main()
{
// Do something
}
这给了我一个编译错误:
use of deleted function 'std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]'
std::atomic_int stop = 0;
^
对于发生了什么有任何想法?
答案 0 :(得分:28)
您的代码正在尝试在RHS上构建临时std::atomic_int
,然后使用std::atomic_int
复制构造函数(delete
d)来初始化stop
,就像这样:
std::atomic_int stop = std::atomic_int(0);
因为你在这里执行的 copy-initialisation 与其他类型的初始化并不完全相同。
[C++11: 8.5/16]:
初始值设定项的语义如下 [..]如果初始化程序是(非括号的)braced-init-list,则对象或引用是 list-initialized (8.5.4)。
(这允许选项3,在此答案的最后)
[..]
如果目标类型是(可能是cv限定的)类类型:
- 如果初始化是直接初始化,或者,如果它是复制初始化,其中源类型的cv-nonqualified版本与或者,目标类的派生类,构造函数被考虑。枚举适用的构造函数(13.3.1.3),并通过重载解析(13.3)选择最佳构造函数。调用所选的构造函数来初始化对象,初始化表达式或表达式列表作为其参数。如果没有构造函数适用,或者重载决策不明确,则初始化是不正确的。
(这几乎描述了你的代码,但并不完全;这里的关键是,或许与直觉相反,std::atomic_int
的构造函数在你的情况下根本不被考虑!)
- 否则(即,对于剩余的复制初始化情况),用户定义的转换序列可以从源类型转换为目标类型或(当使用转换函数时)如13.3.1.4所述列举其派生类,并通过重载决议(13.3)选择最佳的一类。如果无法进行转换或模糊不清,则初始化结构不正确。选择的函数以初始化表达式作为参数调用;如果函数是构造函数,则调用初始化目标类型的cv-nonqualified版本的临时函数。临时是一个prvalue。 调用的结果(对于构造函数的情况是临时的)然后用于 direct-initialize ,根据上面的规则,作为的目标的对象复制初始化。在某些情况下,允许实现通过将中间结果直接构造到正在初始化的对象中来消除此直接初始化中固有的复制;见12.2,12.8。
(这是你的情景;所以,虽然可以省略副本,但仍然可以这样做)
- [..]
无论如何,这里有修复;使用直接初始化或列表初始化:
std::atomic_int stop(0); // option 1
std::atomic_int stop{0}; // option 2
std::atomic_int stop = {0}; // option 3
答案 1 :(得分:-4)
就我而言,我有以下错误(示例):
•尚未声明“ std :: literals”
using namespace std::literals::string_literals;
•std :: random_device {}出现“使用已删除功能”错误
std::random_device device = std::random_device{}
检查您选择的C ++标准是什么。就调试模式而言,我选择了-std = c ++ 17,一切正常。但是在发布模式下,我选择了-std:c ++ 11,出现了大量错误。
更新 在具有远程Linux编译功能的Clion Windows 2018.3上进行了测试。
C ++是一个不断发展的标准:2003年后出现了2011年(C ++ 11),然后是2014年(C ++ 14),现在我们有了2017年(C ++ 17),我们正在为2020年(C ++)工作++ 20)。许多事情正在改变,它们已被弃用,其他功能是新的。如果您想要最新的更新,则应该使用最新的标准,如果您的软件具有不建议使用的代码,则必须使用创建它的标准。