首页 > 解决方案 > std::deque、引用和“pop”

问题描述

我在这里找到了以下代码:

template <typename T>
//some code here

std::queue<T> search_queue; 
std::unordered_set<T> searched;

while (!search_queue.empty()) {
  T& person = search_queue.front(); // 'T& person' is what I'm particularly interested about.
  search_queue.pop();

  // some code here

  if (searched.find(person) == searched.end()) {
    // some code here
  }
}

由于std::queue充当底层容器的包装器,在我们的例子中,它是std::deque我们发现以下关于std::dequepop_front

对已擦除元素的迭代器和引用无效。

因此,T& person一定是一个错误,因为它所引用的元素在引用创建后立即被删除。

是这样吗?

谢谢。

标签: c++referencequeuedeque

解决方案


T& person = search_queue.front(); // 'T& person' is what I'm particularly interested about.
search_queue.pop();

是的,在 之后search_queue.pop(),引用T& person不再有效。

if (searched.find(person) == searched.end()) {

并且这个(可能还有其他代码)成为未定义的行为。\

一个可能的解决方法是

for (;!search_queue.empty(); search_queue.pop()) {
  T& person = search_queue.front(); // 'T& person' is what I'm particularly interested about.


  if (searched.find(person) == searched.end()) {
    // some code here
  }
}

只有在没有ingpop的情况下退出循环之前我们不这样做,并且在我们迭代之前不会弹出。breaksearch_queue

另一种选择是

while (!search_queue.empty()) {
  T person = std::move(search_queue.front());
  search_queue.pop();


  if (searched.find(person) == searched.end()) {
    // some code here
  }
}

我们将前面的元素移出到一个局部变量中。


推荐阅读