Я просмотрел эту страницу, но не могу понять причину того же. Там упоминается, что
"для него более разумно вообще не возвращать никакого значения и требовать от клиентов использования front () для проверки значения в начале очереди"
Но проверка элемента из front () также требует, чтобы этот элемент был скопирован в lvalue. Например, в этом сегменте кода
std::queue<int> myqueue;
int myint;
int result;
std::cin >> myint;
myqueue.push (myint);
/ * здесь временно будет создано на RHS, которое будет назначено результату, и в случае возврата по ссылке результат будет недействительным после операции pop * /
result = myqueue.front(); //result.
std::cout << ' ' << result;
myqueue.pop();
в пятой строке объект cout сначала создает копию myqueue.front (), а затем присваивает ее результату. Итак, в чем разница, функция pop могла бы сделать то же самое.
void std::queue::pop();
).front()
также требует, чтобы этот элемент был скопирован в lvalue» - нет, это не так.front
возвращает ссылку, а не значение. Вы можете проверить значение, к которому оно относится, не копируя его.pop()
. Если вы используете,std::queue<T, std::list<T>>
то не стоит беспокоиться о том, что предоставленная ссылкаfront()
будет аннулирована файломpush()
. Но вы должны знать свой шаблон использования и задокументировать свои ограничения.Ответы:
Он действительно мог сделать то же самое. Причина, по которой этого не произошло, заключается в том, что всплывающий элемент, который вернул всплывающий элемент, небезопасен при наличии исключений (необходимо возвращать по значению и, таким образом, создавать копию).
Рассмотрим этот сценарий (с наивной / выдуманной реализацией pop, чтобы проиллюстрировать мою точку зрения):
Если конструктор копирования T выдает при возврате, вы уже изменили состояние очереди (
top_position
в моей наивной реализации), и элемент удаляется из очереди (и не возвращается). Для всех намерений и целей (независимо от того, как вы поймаете исключение в клиентском коде) элемент в верхней части очереди теряется.Эта реализация также неэффективна в том случае, когда вам не нужно извлекаемое значение (т.е. создается копия элемента, которую никто не будет использовать).
Это можно реализовать безопасно и эффективно с помощью двух отдельных операций (
void pop
иconst T& front()
).источник
pop
? это довольно противоречит интуиции. Ему можно было бы дать имяdrop
, и тогда для всех будет ясно, что он неpop
ничего не вернул. См. Например в википедии .Страница, на которую вы ссылаетесь, отвечает на ваш вопрос.
Чтобы процитировать весь соответствующий раздел:
C ++ разработан с учетом эффективности, с учетом количества строк кода, которые программист должен написать.
источник
pop
которая возвращает значение.pop не может вернуть ссылку на значение, которое было удалено, поскольку оно удаляется из структуры данных, поэтому на что должна ссылаться ссылка? Он может возвращаться по значению, но что, если результат pop нигде не сохраняется? Тогда время тратится на ненужное копирование значения.
источник
pop
возврат и действие возврата может привести к исключению. Очевидно, ему придется удалить элемент, прежде чем он вернет его, а затем, если что-то выбрасывает, элемент может быть безвозвратно утерян.value_type
него есть конструктор перемещения nothrow, но тогда интерфейс очереди будет отличаться в зависимости от того, какой тип объекта вы храните в нем, что не поможет.В текущей реализации это действительно так:
Если pop вернет ссылку, например:
Тогда может произойти сбой следующего кода, поскольку ссылка больше не действительна:
С другой стороны, если он вернет значение напрямую:
Затем вам нужно будет сделать копию, чтобы этот код заработал, что менее эффективно:
источник
Начиная с C ++ 11, можно было бы архивировать желаемое поведение, используя семантику перемещения. Нравится
pop_and_move
. Таким образом, конструктор копирования не будет вызываться, а производительность будет зависеть только от конструктора перемещения.источник
pop
исключения безопасными.Вы можете сделать это полностью:
Или, если вам нужно значение переменной, используйте ссылку:
Рядом с этим: формулировка «более разумный» - это субъективная форма «мы изучили шаблоны использования и обнаружили большую потребность в разделении». (Будьте уверены: язык C ++ развивается нелегко ...)
источник
Думаю, лучшим решением было бы добавить что-нибудь вроде
где value получит всплывающее значение.
Преимущество заключается в том, что это можно реализовать с помощью оператора присваивания перемещения, а использование front + pop сделает копию.
источник