C++:考虑但不调用构造函数的特殊性

Posted

技术标签:

【中文标题】C++:考虑但不调用构造函数的特殊性【英文标题】:C++: Particularities of considering but not calling constructors 【发布时间】:2019-04-03 07:45:38 【问题描述】:

在第二个意图中的cppreference about list-initialization(用于复制列表初始化)它说:

copy-list-initialization(显式和非显式构造函数都被考虑,但只能调用非显式构造函数)

构造函数被“考虑”和实际“调用”有什么区别。为什么要考虑构造函数,它可能无论如何都不会被调用?

【问题讨论】:

我认为这意味着显式构造函数也参与了重载决议,但如果这样的构造函数恰好是最佳匹配,则程序格式错误。 我猜这意味着重载决议在选择重载之前并不关心它是否是显式的。 "为什么会有不同形式的列表初始化?" - 这实际上是一个好问题(尽管它可能不适合 SO 格式)。 C++ 已经有 11(?) 种初始化形式,没有什么特别的原因(而且可能更多的是在新的标准中出现)。有人需要遏制标准委员会。 此问题在此处部分重复,您可以找到至少与上一个问题相关的好信息。请阅读:***.com/questions/13461027/… @Jules 谢谢,删除了额外的问题。 【参考方案1】:

“considered”和“called”之间的区别在于,“considered”意味着候选函数参与重载决议,而“called”意味着它实际上被选为最佳匹配。明确地(双关语不是有意的),这意味着如果在复制列表初始化期间选择了显式构造函数,则它是被禁止的。例如考虑这种情况:

struct String 
  explicit String(int size);
  String(char const *value);
;

String s =  0 ;

在这里,您使用的是隐式转换,其中显式构造函数会更好地匹配,因此编译器理所当然地拒绝它。您需要写String 0 来修复代码。现在想象一下,如果考虑显式构造函数,而前者是合法代码。有一个什么都不做的显式构造函数会很奇怪。

【讨论】:

因此,当显式构造函数将被调用时,第一个构造函数被合法调用,如果显式构造函数不会被考虑,则第二个构造函数被合法称呼?如果第一个构造函数在初始示例中不存在,它会编译吗?

以上是关于C++:考虑但不调用构造函数的特殊性的主要内容,如果未能解决你的问题,请参考以下文章

C++学习 之 类中的特殊函数和this指针

C++类的特殊成员-默认/拷贝/移动构造函数

为啥 C++ 列表初始化也会考虑常规构造函数?

c++拷贝构造函数

C++学习:4拷贝友元

[类和对象]构造和析构