我有点搞不懂为什么下面的代码会这样做:
class Base
{
public:
Base() = default;
Base(const Base &) =delete;
Base &operator=(const Base &) = delete;
Base(const char*) {}
};
class Holder
{
public:
Holder() = default;
private:
// Base b = Base();
Base b2 = {};
};
int main()
{
Holder h;
}在这个版本中,它会编译,但是如果我取消对Base b = Base();的注释,它会给出以下错误:
main.cpp:15:17: error: use of deleted function 'Base::Base(const Base&)'
Base b = Base();
^
main.cpp:5:6: note: declared here
Base(const Base &) =delete;
^我只是无法在标准中找到为什么它试图调用Base b = Base()初始化器的复制构造函数,以及为什么它不调用Base b2 = {} ...或者这只是隐藏在某个段落中的几个单词中的一小部分晦涩难懂?
你能给出一个(简短的)解释为什么会这样吗?
(coliru:http://coliru.stacked-crooked.com/a/c02ba0293eab2ce5 )
发布于 2016-01-19 22:08:08
这是因为,从概念上讲,该行是从Base()构造的,它需要一个复制/移动构造函数。您之所以没有意识到这一点,可能是因为该表达式通常会触发复制省略:一种标准优化。这是C++中的一种。
(31.3) -当尚未绑定到引用(12.2)的临时类对象将被复制/移动到具有相同的cv非限定类型的类对象时,可以通过将临时对象直接构造到被省略的复制/移动的目标中来省略复制/移动操作。
关于Base b2 = {}工作的原因,请参阅
(3.4) -否则,如果初始化器列表没有元素,并且T是具有默认构造函数的类类型,则对象是值初始化的。
你可以只做Base b;。
发布于 2016-01-19 22:10:38
T object = {arg1, arg2, ...};是list initialization的语法。不涉及复制。
T object = T()不是列表初始化。右边的操作数构造一个值初始化的临时数,object是从它移动或复制初始化的。可以省略移动和复制,但类型必须是可移动或可复制的,否则不允许这样做。
发布于 2020-02-07 17:26:28
真正的原因是因为你忘记了关键字"explicit",你应该修改代码
Base(const Base &) =delete;至:
explicit Base(const Base &) = delete;让我解释一下原因,在类"Holder“中,Base b= Base()将:
显式基础()将通过调用构造函数生成一个临时对象"Base()"
Base obj = value;
成为
Base obj(value);
因此,只需添加关键字"explicit“即可解决此问题。^_^
https://stackoverflow.com/questions/34878803
复制相似问题