Я постараюсь дать несколько быстрых ответов на вопросы Q1, Q2 и Q3 (но ни в коем случае не завершенные, вам следует изучить термины, используемые для лучшего понимания). Как предлагают комментарии, остальные более подходят для проверки кода.
Q1 - A) Поскольку ссылка постоянна, компилятор может связать литерал с параметром. Смысл в том, что если функция не может изменить его, то не имеет значения, определен ли объект * / примитив или литерал. Если бы подпись была push(value_type & value)
, то это не сработало бы. Эта функция ожидает непостоянную ссылку на объект / примитив, который позволит вам изменить его. Это не имеет смысла, так как вы не можете изменять литерал, и поэтому не допускается.
B) Да enqueue(Queue const & value)
добавит глубокие копии, но функция не должна принимать копию значения. Если это произойдет, вы скопируете все элементы 2 раза вместо 1 раза. Функция enqueue(Queue const value)
(получение копии) сначала создаст новую очередь value
из параметра, который вы передали функции (см. конструктор копирования ). Затем пройдите через value
и добавьте новые элементы в начало очереди вызова со значениями из них в value
. Таким образом, каждый элемент будет скопирован дважды при построении значения параметра и при добавлении элементов в очередь вызова.
Q2 - Как объяснено в комментариях value_type && value
является ссылкой для пересылки или ссылкой r-value . Более или менее ссылка на значение, которое не было привязано к l-значению . Это позволяет вам эффективно выполнять такие действия, как push(MyObject(1, 2, 3))
(поскольку MyObject(1, 2, 3)
не был привязан к 'l-значению'), или передавать право собственности. (см. Конструктор перемещения )
Q3 - const T & front() const
Первый const
относится к типу возврата (T &), второй const
относится к вызывающему объекту (очереди). front
возвращает ссылку на первый элемент в очереди. T & front()
позволяет вам получить первый элемент и изменить его по ссылке (Да, в некоторых случаях полезно изменить начало очереди). Но если очередь постоянна, то получить первый элемент и изменить его не имеет смысла. Таким образом, вы предоставляете пользователю альтернативу для использования в очереди const, const T & front() const
. Вы по-прежнему получаете ссылку на начало очереди, но ссылка является постоянной, поэтому вы не можете ее изменить. Согласно компилятору - const T & front() const
для постоянной очереди и T & front()
для обычной очереди.