#c #reference #queue #deque
Вопрос:
Я нашел здесь следующий код:
template <typename T>
//some code here
std::queue<T> search_queue;
std::unordered_set<T> searched;
while (!search_queue.empty()) {
Tamp; person = search_queue.front(); // 'Tamp; person' is what I'm particularly interested about.
search_queue.pop();
// some code here
if (searched.find(person) == searched.end()) {
// some code here
}
}
Поскольку std::очередь действует как оболочка базового контейнера, которым в нашем случае является std::deque, мы находим следующее о pop_front std::deque:
Итераторы и ссылки на удаленный элемент становятся недействительными.
Следовательно, Tamp; p должно быть ошибкой, потому что элемент, на который он ссылается, стирается сразу после создания ссылки.
Так ли это?
Спасибо.
Комментарии:
1. Ваши рассуждения верны, а код-нет.
2. То, что ваш связанный код когда-либо работал, связано только с неопределенным поведением, которое, возможно (и ненадежно), является тем поведением, которое вы хотели.
3. чтобы исправить это, сделайте так, чтобы человек не был ссылкой
4. Или исправить это,
pop()
только после того, как вы закончите доступTamp; person
Ответ №1:
Tamp; person = search_queue.front(); // 'Tamp; person' is what I'm particularly interested about.
search_queue.pop();
да, после search_queue.pop()
этого ссылка Tamp; person
больше не действительна.
if (searched.find(person) == searched.end()) {
и это (и, возможно, другой код) становится неопределенным поведением.
Возможным решением является
for (;!search_queue.empty(); search_queue.pop()) {
Tamp; person = search_queue.front(); // 'Tamp; person' is what I'm particularly interested about.
if (searched.find(person) == searched.end()) {
// some code here
}
}
который отличается только тем, что мы этого не pop
делаем, пока не выйдем из цикла без break
ing, и search_queue
не выскакивает, пока мы не повторим.
Альтернативой является
while (!search_queue.empty()) {
T person = std::move(search_queue.front());
search_queue.pop();
if (searched.find(person) == searched.end()) {
// some code here
}
}
где мы перемещаем передний элемент в локальную переменную.