Внешний пакет параметров не раскрывается так, как вы написали, он расширяется следующим образом (внутренний пакет не показан развернутым, поскольку у вас, похоже, нет проблем с этим):
return { (0, T{args...}), (1, T{args...}), (2, T{args}) };
гдецелые числа имеют тип std::size_t
.
(0, T{args...})
- это один элемент инициализатора в скобках. Это выражение, использующее оператор запятой. Оператор запятой сначала вычисляет левую часть (0
), а затем правую (T{args...}
) секунду, возвращая последнюю.
Поскольку оценка 0
не имеет побочного эффекта иего значение отбрасывается оператором запятой, это фактически эквивалентно
return { T{args...}, T{args...}, T{args...} };
Есть одно предупреждение. Оператор запятой может быть перегружен. Если существует перегрузка, принимающая std::size_t
в качестве первого и T
в качестве второго аргумента, то это будет вести себя неожиданным образом, вместо этого инициализируя возвращаемое значение, будет результат перегрузки. Этого можно избежать, приведя целое число к void
(которое никогда не может появиться в качестве аргумента для перегруженного вызова оператора):
return { (void(Ints), T{args...})... };