jeudi 30 juillet 2015

I tested the following code on Visual Studio and it compiles and prints "A(double)".

#include <iostream>
#include <initializer_list>

struct A {
    A(const std::initializer_list<int>&) { puts("initializer_list<int>"); }     // (1)
    A(const std::initializer_list<float>&) { puts("initializer_list<float>"); } // (2)
    A(double) { puts("A(double)"); }                                            // (3)
};

int main() {
    A var{ 1.1 };   
}

However both IntelliSense and http://ift.tt/1KBl1ug disagree, saying that more than one instance of constructor "A::A" matches the argument list (meaning both initializer-list constructors). Note that if either (1) or (2) is removed, code does not compile anymore, as "conversion from 'double' to 'float' requires a narrowing conversion".

Is this a bug? The behaviour feels inconsistent, but I see the same behaviour in VS13 and VS15 so maybe there is more to it?

But my real question is regarding the relevant section in standard.

3 List-initialization of an object or reference of type T is defined as follows:

  • ...
  • (3.5) — Otherwise, if T is a specialization of std::initializer_list, a prvalue initializer_list object is constructed as described below and used to initialize the object according to the rules for initialization of an object from a class of the same type (8.5).
  • (3.6) — Otherwise, if T is a class type, constructors are considered. ...

I don not understand (3.5), particularly the highlighted part - does it simply mean that type T has some initializer-list constructor?

Aucun commentaire:

Enregistrer un commentaire