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

C++: Particularities of considering but not calling constructors

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

copy-list-initialization (both explicit and non-explicit constructors are considered, but only non-explicit constructors may be called)

构造函数 'considered' 和实际 'called' 的区别究竟是什么?为什么要考虑可能无论如何都不会调用的构造函数?

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

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

String s = { 0 };

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