在标准文本中有一个例子在8.5.4 (3) List-initialization [dcl.init.list]
struct S {
S(std::initializer_list<double>); // #1
S(const std::string&); // #2
};
const S& r1 = { 1, 2, 3.0 }; // OK: invoke #1
const S& r2 { "Spinach" }; // OK: invoke #2 !!!
(这个例子是关于 ref-to-temp,但我在这里指的是重载解决方案)。
而斯科特迈耶斯在他的演讲/幻灯片中讲述了一个不同的故事:
std::initializer_list 参数总是优先于其他类型:
class Widget {
public:
Widget(double value, double uncertainty); // #1
Widget(std::initializer_list<std::string> values); // #2
};
double d1, d2;
Widget w1 { d1, d2 }; // tries to call #2; fails because
// no double ⇒ string conversion
这些例子略有不同,但不是同一件事吗?何时以及如何使用initializer_list
-constructors 进行重载解析?还是这里有不同的问题?
两种情况下的超载是如何决定的?如果两者都是正确的,我在这里错过了什么?
编辑/澄清Keric的评论:我的感觉是,这两个例子相互矛盾:
- Std 给出了一个示例,其中 a
const char*
转换为 astring
,它与提供的不匹配initializer_list<int>
,因此使用提供的“正常”const string&
-c'tor。 - Scott 的示例在-c'tor 可用并因此被选择
{double, double}
时进行初始化,因为他认为该列表是首选。intializer_list<int>
因此,以(double, double)
这种方式初始化时,永远不会选择还提供的 -c'tor。
当然,Std 总是正确的,但也许我错误地应用了这个例子。Std 示例&
中有,我认为这与我的问题无关,但也许我错了。
Scott 的幻灯片是最新的,我看不到标准中的相关部分已经改变到这方面(尽管很难将所有内容都纳入范围,因为它有点“广泛传播”:-)
编辑 2:我收到了 Scott 本人的一封邮件,说标准中有一个后期更改尚未纳入幻灯片。