C ++ 0x:重载决议

时间:2011-07-19 08:51:40

标签: c++11 overloading initializer-list

在标准文本中, 8.5.4(3)列表初始化[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,但我在这里指的是重载决策。)

Scott Meyers在他的演讲/幻灯片中讲述了一个不同的故事:

  

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 - 构造函数进行重载解析?或者这里有不同的问题吗?

两种情况下如何确定重载?如果两者都正确,我在这里想念什么?

Keric的

编辑/澄清评论:我的感觉是,这两个例子相互矛盾:

  • Std举例说明const char*转换为string,与提供的initializer_list<int>不匹配,因此提供的“正常”const string& - c '使用了。
  • {double, double} - c'tor可用并因此被选中时,Scott的示例用intializer_list<int>初始化,因为他认为该列表是首选。因此,当以这种方式初始化时,也永远不会选择(double, double) - c'tor。

当然,Std总是对的,但也许我错误地应用了这个例子。标准示例中有&,我认为这与我的问题无关,但也许我错了。

斯科特的幻灯片是最新的,我看不出Std中的相关部分已经改变了这个方面(尽管,很难将所有内容都纳入范围,因为它有点“广泛传播”:-)

编辑-2 :我收到了斯科特本人的一封邮件,其中有late change in the Standard未合并到幻灯片中。

1 个答案:

答案 0 :(得分:5)

根据N3291,2011年4月5日的工作草案,初始化程序列表有一些变化,因此Scott Meyer的幻灯片可能来自旧数据。

根据第13.3.1.7节(如此接近1337):

  
      
  • 最初,候选函数是类T的初始化列表构造函数(8.5.4),参数列表由初始化列表作为单个参数组成
  •   
  • 如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中候选函数是类T的所有构造函数,参数列表由初始化列表的元素组成。
  •   

所以它确实更喜欢initailizer列表。但是如果初始化列表不匹配,那么它将检查常规构造函数以查看它们是否匹配。

接着说,如果初始化列表为空,则使用默认构造函数。