【发布时间】:2010-11-09 12:56:29
【问题描述】:
std::queue::front 会取消前面的元素吗?如果没有怎么删除呢?
【问题讨论】:
std::queue::front 会取消前面的元素吗?如果没有怎么删除呢?
【问题讨论】:
有一个获取元素的函数,另一个用于删除元素的函数:
typedef queue<MyClass> MyQueue;
MyQueue q;
q.push(MyClass(42));
// ...
MyClass const& rx = q.front();
rx.print();
MyClass x = q.front(); // Copies the front element to a fresh object
q.pop(); // From this point, rx is a dangling reference
assert(x == MyClass(42));
基本原理:如果只有一个 pop 函数返回前面的元素,则不可能获得对前面元素的引用,因为它会从队列中删除。如果您只想在丢弃之前读取一个巨大的元素,那么您肯定不希望您的代码执行复制。
编辑:一个更根本的原因是拥有两个功能意味着用户负责制作副本。假设只有一个pop 函数:如果复制构造函数(pop 内部)抛出异常会发生什么? (参见@Steve Jessop 的评论)
【讨论】:
interface,因为您可以同时拥有front 和返回副本的pop。要么是这种行为,要么是要求复制构造函数不能抛出。
MyClass x; x = q.pop(); 异常安全.正如我们所知,这在 C++ 中是不可行的。一个更简单的替代方法是pop 采用非常量引用参数,并在修改队列之前将前端对象复制到该参数中。这很容易成为异常安全的,AFAIK 不提供它的原因只是它是front() 和pop() 的简单组合,所以可以自己动手做。
queue.pop(item) 来完成,使用赋值而不是复制构造。我猜这不太惯用。
不,它只是返回对前面元素的引用。如果您需要取出元素,请使用pop()。有关详细信息,请参阅std::queue 参考。
【讨论】:
队列前端操作的类型定义。
value_type& queue::front ()
const value_type& queue::front () const
两种形式都返回队列的下一个元素。调用者必须确保队列包含一个元素(size()>0);否则,行为未定义。非常量队列的第一种形式返回一个引用。因此,您可以修改队列中的下一个元素。由您决定这是否是好的风格。
使用 pop 删除它。它从队列中删除下一个元素。下一个元素是最先插入的元素(在队列中的所有其他元素之前)。这个函数没有返回值。要处理下一个元素,您必须先调用 front()。
【讨论】: