16 Overloading [over]

16.3 Overload resolution [over.match]

16.3.3 Best viable function [over.match.best]

16.3.3.1 Implicit conversion sequences [over.best.ics]

16.3.3.1.5 List-initialization sequence [over.ics.list]

Когда аргумент является списком инициализатора ([dcl.init.list]), это не выражение, и для его преобразования в тип параметра применяются специальные правила.

Если тип параметра является агрегатным классом, X а список инициализаторов имеет единственный элемент типа cv U, где U is X или класс, производный от X, неявная последовательность преобразования - это последовательность, необходимая для преобразования элемента в тип параметра.

В противном случае, если тип параметра является символьным массивом,133 а в списке инициализаторов есть единственный элемент, который является строковым литералом соответствующего типа ([dcl.init.string]), неявная последовательность преобразования является преобразованием идентичности.

В противном случае, если тип параметра равен std​::​initializer_­list<X> и все элементы списка инициализатора могут быть неявно преобразованы в X, последовательность неявного преобразования является наихудшим преобразованием, необходимым для преобразования элемента списка в X, или, если список инициализатора не имеет элементов, идентификатор конверсия. Это преобразование может быть определенным пользователем преобразованием даже в контексте вызова конструктора списка инициализаторов. [Example:

void f(std::initializer_list<int>);
f( {} );                // OK: f(initializer_­list<int>) identity conversion
f( {1,2,3} );           // OK: f(initializer_­list<int>) identity conversion
f( {'a','b'} );         // OK: f(initializer_­list<int>) integral promotion
f( {1.0} );             // error: narrowing

struct A {
  A(std::initializer_list<double>);             // #1
  A(std::initializer_list<complex<double>>);    // #2
  A(std::initializer_list<std::string>);        // #3
};
A a{ 1.0,2.0 };         // OK, uses #1

void g(A);
g({ "foo", "bar" });    // OK, uses #3

typedef int IA[3];
void h(const IA&);
h({ 1, 2, 3 });         // OK: identity conversion

end example]

В противном случае, если тип параметра - «массив из N X», если существует неявная последовательность преобразования для каждого элемента массива из соответствующего элемента списка инициализаторов (или из, {} если такого элемента нет), последовательность неявного преобразования является худшая такая последовательность неявного преобразования.

В противном случае, если параметр не является совокупным учащимся X и Разрешением перегрузки PER [over.match.list] выбирает один лучший конструктором C из X выполнить инициализацию объекта типа X от аргумента инициализатора списка:

  • Если C это не конструктор списка инициализаторов, а список инициализаторов имеет единственный элемент типа cv U, где U is X или класс, производный от X, неявная последовательность преобразования имеет ранг точного соответствия, если он U есть X, или ранг преобразования, если U является производным от X.

  • В противном случае неявная последовательность преобразования является пользовательской последовательностью преобразования, а вторая стандартная последовательность преобразования является преобразованием идентичности.

Если жизнеспособны несколько конструкторов, но ни один из них не лучше других, последовательность неявного преобразования является последовательностью неоднозначного преобразования. Пользовательские преобразования разрешены для преобразования элементов списка инициализаторов в типы параметров конструктора, за исключением случаев, указанных в [over.best.ics]. [Example:

struct A {
  A(std::initializer_list<int>);
};
void f(A);
f( {'a', 'b'} );        // OK: f(A(std​::​initializer_­list<int>)) user-defined conversion

struct B {
  B(int, double);
};
void g(B);
g( {'a', 'b'} );        // OK: g(B(int, double)) user-defined conversion
g( {1.0, 1.0} );        // error: narrowing

void f(B);
f( {'a', 'b'} );        // error: ambiguous f(A) or f(B)

struct C {
  C(std::string);
};
void h(C);
h({"foo"});             // OK: h(C(std​::​string("foo")))

struct D {
  D(A, C);
};
void i(D);
i({ {1,2}, {"bar"} });  // OK: i(D(A(std​::​initializer_­list<int>{1,2}), C(std​::​string("bar"))))

end example]

В противном случае, если параметр имеет тип агрегата, который может быть инициализирован из списка инициализаторов в соответствии с правилами для aggregate initialization, неявная последовательность преобразования является пользовательской последовательностью преобразования, а вторая стандартная последовательность преобразования является преобразованием идентичности. [Example:

struct A {
  int m1;
  double m2;
};

void f(A);
f( {'a', 'b'} );        // OK: f(A(int,double)) user-defined conversion
f( {1.0} );             // error: narrowing

end example]

В противном случае, если параметр является справочным, см [over.ics.ref]. [ Note: Правила в этом разделе будут применяться для инициализации базового временного объекта для ссылки. ] [ end noteExample:

struct A {
  int m1;
  double m2;
};

void f(const A&);
f( {'a', 'b'} );        // OK: f(A(int,double)) user-defined conversion
f( {1.0} );             // error: narrowing

void g(const double &);
g({1});                 // same conversion as int to double

end example]

В противном случае, если тип параметра не является классом:

  • если в списке инициализаторов есть один элемент, который сам не является списком инициализаторов, неявная последовательность преобразования является той, которая требуется для преобразования элемента в тип параметра; [Example:

    void f(int);
    f( {'a'} );             // OK: same conversion as char to int
    f( {1.0} );             // error: narrowing
    

    end example]

  • если список инициализаторов не имеет элементов, неявная последовательность преобразования является преобразованием идентичности. [Example:

    void f(int);
    f( { } );               // OK: identity conversion
    

    end example]

Во всех случаях, кроме перечисленных выше, преобразование невозможно.

Поскольку нет параметров типа массива, это будет происходить только как ссылочный тип ссылочного параметра.