dimanche 31 janvier 2016

Worst conversion sequence in list-initialization

I don't understand how worst conversion sequences for initializer_list are ranked during overload resolution. For example:

#include <initializer_list>

void fnc (std::initializer_list<int>){}
void fnc (std::initializer_list<long>){}

struct CL1 {
    operator short(){return 1;} };

struct CL2 {
    operator short(){return 1;} };

int main() {
    CL1 cl1;
    CL2 cl2;
    fnc ({cl1, cl2});
}

Here is a call of overloaded fnc function and overload resolution finds the best-viable function. The candidates are 2 functions which are ranked by comparing their needed conversion sequences.

The Standard (n4296) 13.3.3.1.5/4 [over.ics.list] says:

Otherwise, if the parameter type is std::initializer_list and all the elements of the initializer list can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary to convert an element of the list to X

For std::initializer_list<int> both conversions (CL1 -> int, CL2 -> int) are indistinguishable and both can be worst conversion (user-defined conversion + promotion). Simularly for std::initializer_list<long>, but with worst conversion sequence as user-defined conversion + standard conversion. And then the main question: which conversion (for cl1 or cl2) is selected as worst? Assume that in both initializer lists the worst conversion is selected as first (for cl1). Then, according to 13.3.3.2/3.3 [over.ics.rank]

User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2.

the case with int is better because its second standard conversion sequence is better (promotion against standard conversion) and both conversions contain the same operator short(). Then assume that for std::initializer_list<long> worst conversion is for second element (cl2), and here is ambuguity because conversion functions are different.

Aucun commentaire:

Enregistrer un commentaire