mercredi 21 janvier 2015

Why is this initializer_list constructor a viable overload?

From 13.3.2 [over.match.viable]



Second, for F to be a viable function, there shall exist for each argument an implicit conversion sequence that converts that argument to the corresponding parameter of F.



From 4 [conv]



An expression e can be implicitly converted to a type T if and only if the declaration T t=e; is well-formed, for some invented temporary variable t.



From 8.5.1 [dcl.init.aggr]



If the initializer-clause is an expression and a narrowing conversion is required to convert the expression, the program is ill-formed.



Using 8.5.1 and 4, since the following is not well-formed



std::initializer_list<int> e = {1, 1.0};


{1, 1.0} is not implicitly convertible to std::initializer_list<int>.


Using the quote from 13.3.2, shouldn't it imply that A::A(std::initializer_list<int>) isn't a viable function when doing overload resolution for A a1 = {1, 1.0};? Finding no viable initializer_list constructors, shouldn't this statement pick A::A(int, double)?



#include <iostream>
#include <string>
#include <initializer_list>

class A
{
public:
A(int, bool) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
A(int, double) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
A(std::initializer_list<int>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

int main()
{
A a1 = {1, 1.0};
return 0;
}


(This question is a follow-up to this.)


Aucun commentaire:

Enregistrer un commentaire