1) {1, 2}
не является выражением
Синтаксис
{1, 2}
очень "странный" по сравнению с другими вещами в C ++.
Обычно в C ++у вас есть выражение (например, x + 1.2
), и выражение имеет выведенный тип ... например, если x
является переменной int
, тип выражения будет double
из-за неявного преобразования int
→double
и как работает сложение.
Теперь вернемся к {1, 2}
: это "странно", потому что, несмотря на то, что выражение выглядит не так, оно не ... это просто синтаксис, и его значение будет зависеть от того, где оно используется.
В некотором смысле ввод здесь будет работать противоположно большинству мест C ++: обычно в C ++ это «in» → «out» (тип «появляется» из компонентов), но здесь «out» → »in«(тип« внедряется »в компоненты).
Текст {1, 2}
сам по себе не достаточно значит для компиляции (это может означать разные вещи в зависимости от того, где он используется).
Все это сводится к тому, что {1, 2}
нельзя использовать в точности как выражение, даже если правила тщательно разработаны, чтобы обмануть вас.
2) emplace_back
принимает параметры конструктора
emplace_back
был разработан, чтобывозможность создания объекта непосредственно внутри конечного места в контейнере ... ожидаемые параметры - это параметры конструктора, и это делается для того, чтобы избежать создания временного объекта, просто чтобы иметь возможность сделать копию для конечного пункта назначения и затем выбросить его,Следовательно, ожидаемый параметр emplace_back
- это 1
и 2
... не одно и то же, потому что НЕ построение временного отдельного объекта является именно той причиной, для которой emplace_back
был разработан.
Вы можете передатьemplace_back
экземпляр, поскольку содержащийся тип имеет конструктор копирования, а экземпляр считается параметром для конструктора копирования (перемещения), а не объекта, который нужно скопировать (переместить) в место назначения (что ожидает push_back
).Операции, выполняемые в этом случае, одинаковы, но с другой точки зрения.
Последствия
Подводя итог: emplace_back
не может использовать {1, 2}
, потому что может принимать все (так ненедостаточно контекста), и этот синтаксис не имеет достаточного значения.push_back
вместо этого может принять его, потому что он ожидает определенного типа, и это обеспечивает достаточный контекст для интерпретации синтаксиса {1, 2}
.Это упрощенное объяснение, но, как обычно, C ++ пошел в направлении еще большей сложности разбора и особых случаев, поэтому я могу понять, почему вам что-то не понятно.
Однако ключевой момент заключается в том, что emplace_back
не должен был брать полный объект ... для этого использования push_back
.Новая конструкция emplace_back
должна использоваться, когда вы хотите передать ПАРАМЕТРЫ КОНСТРУКТОРА для построения конечного объекта в контейнере.