Jeruntu
Jeruntu

Reputation: 188

Copy list initialisation and explicit constructor allowed?

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

Answers (1)

TartanLlama
TartanLlama

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

Related Questions