В этом случае {1, 2, 3}
не может быть выведено до initializer_list<int>
(именно этого ожидает конструктор vector<int>
, который вы хотите использовать.) Так что вам нужно немного помочь:
matrix.emplace_back(initializer_list<int>{1, 2, 3});
Это не требуется при использовании push_back()
. Я не знаю точных деталей, но emplace_back()
- это шаблон функции, а push_back()
- нет. Правила удержания для шаблонов различны (более строгие). И у инициализатора в скобках нет типа. Из-за этого у него есть свои особые правила о том, как работает вывод типов.
По сути, это:
matrix.emplace_back(vector<int>{1, 2, 3});
создает два вектора. Пустой вектор в matrix
, и переданный временный. Временный перемещается в пустой вектор. Так что все не так уж и плохо.
Однако это:
matrix.emplace_back(initializer_list<int>{1, 2, 3});
Создает только один вектор, используя конструктор, который принимает initializer_list. Обратите внимание, что здесь не создается «лишний» initializer_list
объект. Такой объект будет создан в любом случае при создании любого вектора с использованием фигурной инициализации:
vector<int> vec{1, 2, 3};
Это также создает initializer_list
объект, потому что это то, что принимает векторный конструктор.
Что касается того, почему emplace_back(2,3)
работает, это потому, что есть векторный конструктор, который принимает размер и значение.