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

Copy list initialisation and explicit constructor allowed?

本文关键字:初始化 构造函数 列表 许复制 复制      更新时间:2023-10-16

我在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]中,有如下说明:

在复制列表初始化中,如果选择了显式构造函数,则 初始化格式不正确。

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

是的,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是否应将其用于此形式的初始化。