Reputation: 188
I am using the following code in VS2013 and it compiles.
explicit QIcon(const QString &fileName); // file or resource name
void setWindowIcon(const QIcon &icon);
I call the function like this:
setWindowIcon({ "icon.png" });
However in Clang 3.7.1 it fails with:
error chosen constructor is explicit in copy-initialization
I read in other questions that in the C++ standard, §13.3.1.7 [over.match.list], the following is stated:
In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed.
Is VS2013 wrong in allowing this code to compile?
Upvotes: 1
Views: 1379
Reputation: 65620
Yes, VS2013 is wrong in allowing the code to compile.
The important rule is in [over.ics.list]
(quote from 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
outlines implicit conversion sequences, which references [class.conv.ctor]
regarding user-defined conversions:
[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.
So the constructor must not be marked explicit
if it should be used for this form of initialization.
Upvotes: 3