我有一个名为Thing
的对象,其构造函数采用int。
此代码按预期工作:
Thing thing(5);
然而,偶然的我写了以下内容:
Thing thing = Thing(5); // note: no 'new'
得到错误no matching constructor for initialization of 'Thing'
。后一个代码的实际含义是什么?我知道如果我在那里抛出一个new
意味着什么,但没有新的,这是什么意思?
答案 0 :(得分:10)
Thing thing = Thing(5);
需要定义(非explicit
)副本(或移动) - 构造函数:
Thing(const Thing &);
(即使出于优化原因没有调用它)。
答案 1 :(得分:9)
Thing thing(5);
为direct initliazation,thing
由apporiate构造函数(即Thing::Thing(int)
)直接构建。
Thing thing = Thing(5);
是copy initialization,这与直接初始化不完全相同。但是对于这种情况,从C ++ 17开始,它将直接调用Thing::Thing(int)
来构造对象,然后它与直接初始化具有相同的效果。
首先,如果
T
是一个类类型,并且初始化程序是一个prvalue表达式,其cv-unqualified类型与T
是同一个类,则初始化程序表达式本身,而不是从它实现的临时表达式,用于初始化目标对象:请参阅copy elision
在C ++ 17之前,第二种情况(即复制初始化)要求复制/移动构造函数是可访问和非显式的;如果是这种情况并且您使用的编译器不支持C ++ 17,则会导致错误。
如果
T
是类类型且other
类型的cv-nonqualified版本是T
或从T
派生的类,则非显式构造函数检查T
,并通过重载决策选择最佳匹配。然后调用构造函数来初始化对象。
请注意,从C ++ 17开始,代码编译正常。根据{{3}}的规则,对于这种情况,复制/移动构造函数不需要是可访问的explicit
。
在下列情况下,编制者需要省略 类对象的复制和移动构造函数,即使复制/移动也是如此 构造函数和析构函数具有可观察到的副作用:
在初始化中,如果初始化表达式是prvalue,并且源类型的cv-nonqualified版本与 目的地的类,初始化表达式用于 初始化目标对象:
T x = T(T(T())); // only one call to default constructor of T, to initialize x