Из справки по CPP по инициализации списка:
В противном случае конструкторы T рассматриваются в два этапа:
Все конструкторы, которые принимают std::initializer_list в качестве единственного аргумента или в качестве первого аргумента, если остальные аргументы имеют значения по умолчанию, проверяются и сопоставляются разрешением перегрузки с одним аргументом типа std::initializer_list.
Если предыдущий этап не дает совпадения, все конструкторы T участвуют в разрешении перегрузки для набора аргументов, состоящего из элементов braced-init-list, с ограничением, что разрешены только не сужающие преобразования. Если на этом этапе создается явный конструктор как наилучшее соответствие для инициализации списка копирования, компиляция завершится ошибкой (обратите внимание, что при простой инициализации копированием явные конструкторы вообще не учитываются).
Таким образом, конструктор, использующий initializer_list
, рассматривается первым. В противном случае каждый элемент списка рассматривается как аргумент для конструкторов. тем не мение
#include <iostream>
using namespace std;
struct A{
template <typename... Args> A(Args... li) { cout << sizeof...(Args) << endl;}
};
int main(){
A a = {2,3,4};
}
Результатом является 3
, что указывает на то, что Args...
распаковывается как int, int, int
. Почему Args... не был просто преобразован в единственное число initializer_list<int>
, которое, как указывалось в деталях инициализации списка, будет первым предпринятым типом конструктора?