允许复制列表初始化和显式构造函数?

时间:2016-02-11 10:39:28

标签: c++ c++11 visual-studio-2013 clang language-lawyer

我在VS2013中使用以下代码并进行编译。

explicit QIcon(const QString &fileName); // file or resource name
void setWindowIcon(const QIcon &icon);

我这样称呼函数:

setWindowIcon({ "icon.png" });

然而在Clang 3.7.1中,它失败了:

  

错误选择的构造函数在复制初始化中是显式的

我在其他问题中读到,在C ++标准§13.3.1.7[over.match.list]中,陈述如下:

  

在copy-list-initialization中,如果选择了显式构造函数,则   初始化是不正确的。

VS2013是否允许此代码编译错误?

1 个答案:

答案 0 :(得分:2)

是的,VS2013允许代码编译是错误的。

重要规则在[over.ics.list](引自N3337):

  

[over.ics.list]/1]:当参数是初始化列表(8.5.4)时,它不是表达式,并且特殊规则适用于转换   它是一个参数类型。

     

[over.ics.list]/3]:否则,如果参数是非聚合类X,并且每13.3.1.7的重载决策选择一个   X的最佳构造函数,用于从参数初始化列表中执行类型X的对象的初始化   隐式转换序列是用户定义的转换序列。如果多个构造函数可行但是   没有比其他更好的,隐式转换序列是模糊的转换序列。 允许用户定义的转换将初始化列表元素转换为构造函数参数   除了13.3.3.1 中所述的类型。

13.3.3.1概述了隐式转化序列,引用[class.conv.ctor]有关用户定义的转化:

  

[class.conv.ctor]/1:声明而没有明确的函数说明符的构造函数指定从其类型转换   参数类型的类。这样的构造函数称为转换构造函数。

因此,如果构造函数应该用于这种初始化形式,则不能将其标记为explicit