允许复制列表初始化和显式构造函数吗?
Copy list initialisation and explicit constructor allowed?
我在 VS2013 中使用以下代码并编译。
explicit QIcon(const QString &fileName); // file or resource name
void setWindowIcon(const QIcon &icon);
我这样调用函数:
setWindowIcon({ "icon.png" });
但是在 Clang 3.7.1 中它失败了:
error chosen constructor is explicit in copy-initialization
我在其他问题中读到,在 C++ 标准 §13.3.1.7 [over.match.list] 中,陈述如下:
In copy-list-initialization, if an explicit constructor is chosen, the
initialization is ill-formed.
VS2013让这段代码编译是不是错了?
是的,VS2013 允许代码编译是错误的。
重要规则在[over.ics.list]
(引自N3337):
[over.ics.list]/1]:
When an argument is an initializer list (8.5.4), it is not an expression and special rules apply for converting
it to a parameter type.
[over.ics.list]/3]:
Otherwise, if the parameter is a non-aggregate class X and overload resolution per 13.3.1.7 chooses a single
best constructor of X to perform the initialization of an object of type X from the argument initializer list, the
implicit conversion sequence is a user-defined conversion sequence. If multiple constructors are viable but
none is better than the others, the implicit conversion sequence is the ambiguous conversion sequence. User-defined conversions are allowed for conversion of the initializer list elements to the constructor parameter
types except as noted in 13.3.3.1.
13.3.3.1
概述隐式转换序列,其中引用 [class.conv.ctor]
关于用户定义的转换:
[class.conv.ctor]/1:
A constructor declared without the function-specifier explicit specifies a conversion from the types of its
parameters to the type of its class. Such a constructor is called a converting constructor.
因此如果构造函数应该用于这种形式的初始化,则不能标记为explicit
。
我在 VS2013 中使用以下代码并编译。
explicit QIcon(const QString &fileName); // file or resource name
void setWindowIcon(const QIcon &icon);
我这样调用函数:
setWindowIcon({ "icon.png" });
但是在 Clang 3.7.1 中它失败了:
error chosen constructor is explicit in copy-initialization
我在其他问题中读到,在 C++ 标准 §13.3.1.7 [over.match.list] 中,陈述如下:
In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.
VS2013让这段代码编译是不是错了?
是的,VS2013 允许代码编译是错误的。
重要规则在[over.ics.list]
(引自N3337):
[over.ics.list]/1]:
When an argument is an initializer list (8.5.4), it is not an expression and special rules apply for converting it to a parameter type.
[over.ics.list]/3]:
Otherwise, if the parameter is a non-aggregate class X and overload resolution per 13.3.1.7 chooses a single best constructor of X to perform the initialization of an object of type X from the argument initializer list, the implicit conversion sequence is a user-defined conversion sequence. If multiple constructors are viable but none is better than the others, the implicit conversion sequence is the ambiguous conversion sequence. User-defined conversions are allowed for conversion of the initializer list elements to the constructor parameter types except as noted in 13.3.3.1.
13.3.3.1
概述隐式转换序列,其中引用 [class.conv.ctor]
关于用户定义的转换:
[class.conv.ctor]/1:
A constructor declared without the function-specifier explicit specifies a conversion from the types of its parameters to the type of its class. Such a constructor is called a converting constructor.
因此如果构造函数应该用于这种形式的初始化,则不能标记为explicit
。