当将构造函数标记为已删除时,即
class MyClass {
// ...
MyClass(int x) = delete;
// ...
};
将已删除的构造函数标记为 有什么影响吗explicit
?即
explicit MyClass(int x) = delete;
?
当将构造函数标记为已删除时,即
class MyClass {
// ...
MyClass(int x) = delete;
// ...
};
将已删除的构造函数标记为 有什么影响吗explicit
?即
explicit MyClass(int x) = delete;
?
是的,
= delete
不会影响过载解析,除非最终过载解析会选择一个被删除的过载,那么该过载解析将被视为格式不正确。= delete
不会修改过载解析的决策过程。explicit
确实会极大地影响过载解析,因为它会改变构造函数是否作为候选者参与不同的过载解析场景。这两个结构是正交的。添加或删除其中一个并不意味着应该添加或删除另一个。
例子:
explicit
第一个构造函数没有,MyClass x = 0;
是格式错误的,因为重载解析会优先选择第一个构造函数。如果使用explicit
第一个构造函数,则不会考虑复制初始化,而是选择第二个构造函数(否则匹配度会更差)。初始化不会格式错误。另一方面,对于形式为 的初始化
MyClass x(0);
(即直接初始化),始终会考虑所有构造函数,并且重载解析将选择第一个构造函数,无论是否是explicit
。因此,这种初始化将始终是格式错误的。因此,在这个例子中,您需要决定是否只希望从格式不正确的进行显式转换(同时仍然允许从进行隐式和显式转换)或者是否希望从格式不正确的进行隐式和显式转换。
int
long
long
即使这是该类的唯一构造函数,仍然存在差异。
假设有一个函数重载集
和
然后尝试调用
f(0)
是符合格式的,因为第一个重载不可行。explicit
在重载解析中,构造函数不被视为函数参数的隐式转换序列。只有第二个重载是可行的,才会被选中。但如果没有
explicit
,则两个重载都变得可行,重载解析将变得不明确。构造函数是否被删除对于此确定无关紧要。删除构造函数意味着您希望特定的重载解析结果导致初始化格式不正确。在决定哪种格式不正确时,您始终必须考虑是否应
explicit
应用,就像定义非删除重载时一样。