您的代码试图std::atomic_int
在 RHS 上构造一个临时对象,然后使用std::atomic_int
复制构造函数(即delete
d)来初始化stop
,如下所示:
std::atomic_int stop = std::atomic_int(0);
那是因为copy-initialisation,正如您在此处执行的那样,并不完全等同于其他类型的初始化。
[C++11: 8.5/16]:
初始化器的语义如下[..]
如果初始值设定项是(无括号的)大括号初始化列表,则对象或引用是列表初始化的(8.5.4)。
(这允许选项3,在这个答案的末尾)
[..]
如果目标类型是(可能是 cv 限定的)类类型:
- 如果初始化是直接初始化,或者如果是复制初始化,其中源类型的 cv 非限定版本与目标类相同或派生类,则考虑构造函数。枚举了适用的构造函数(13.3.1.3),并通过重载决议(13.3)选择最佳构造函数。调用如此选择的构造函数来初始化对象,使用初始化表达式或表达式列表作为其参数。如果没有构造函数适用,或者重载决议不明确,则初始化格式错误。
(这几乎描述了您的代码,但并不完全;这里的关键是,也许与直觉相反,std::atomic_int
在您的情况下根本不考虑 ' 的构造函数!)
- 否则(即,对于剩余的复制初始化情况),可以从源类型转换到目标类型或(当使用转换函数时)到其派生类的用户定义转换序列被枚举,如 13.3 中所述。 1.4,最好的一个是通过重载决议(13.3)选择的。如果转换无法完成或不明确,则初始化格式错误。以初始化表达式作为参数调用所选函数;如果函数是构造函数,则调用初始化目标类型的 cv 非限定版本的临时版本。临时是prvalue。然后使用调用的结果(这是构造函数情况的临时结果)直接初始化,根据上面的规则,作为复制初始化目标的对象。在某些情况下,允许实现通过将中间结果直接构造到正在初始化的对象中来消除这种直接初始化中固有的复制;见 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