为什么C++的std::vector没有pop_front方法?
std::vector
在插入元素方面没有特别的功能。每个容器提供的功能对于该容器都是有意义的。std::deque
,它明确地擅长在前端和后端插入元素。虽然对于大向量效率较低,但以下内容等同于std::vector
的pop_front()
vec.erase(vec.begin());
正如其他答案所述,std::vector
并不适合删除第一个元素,并且需要移动/复制所有剩余的元素。根据具体的使用情况,考虑使用其他容器可能更为方便。
vector通常被实现为以下样式:
struct
{
T* begin; // points to the first T in the vector
T* end; // points just after the last T in the vector
int capacity; // how many Ts of memory were allocated
};
struct
{
T* allocated; // points to all the memory we allocated
T* begin; // points to the first T in the vector
T* end; // points just after the last T in the vector
int capacity; // how many Ts of memory were allocated
};
通过这种方式,您可以通过将“begin”向前和向后移动来执行“pop_front”,而不必担心稍后需要释放哪个内存。为什么std::vector不能以这种方式工作呢?我想这是标准撰写人员口味的问题。他们的目标可能是提供尽可能简单的“动态可调整大小的数组”,我认为他们成功了。
push_back
和pop_back
是向量的特殊操作,只需要O(1)
的计算。任何其他的push或pop都需要O(n)
。pop_front()
操作,可以考虑改用std::deque<>
。 - ildjarnpush_back
并不总是需要重新分配空间。 - Lightness Races in Orbit然而,如果你需要进行pop_front操作并且不关心向量中元素的索引,你可以使用类似以下方法进行类似于pop_front的操作:
template<typename T>
void pop_front(std::vector<T>& vec)
{
vec.front() = vec.back();
vec.pop_back();
}
Dan Higgins也谈到了这个问题:https://youtu.be/oBbGC-sUYVA?t=2m52s
template<typename T> void pop_front(std::vector<T>& v) { v.pop_back(); }
,你将无法删除预期的 front
元素。我的建议是“交换” front
和 back
元素并删除最后一个元素。 - marchelblingpop_front
的有效方法。 - marchelbling#define push_front(v,val) v.insert(v.begin(), 1, val);
#define pop_front(v) if(!v.empty())v.erase(v.begin());
push_front(vec,val);
pop_front(vec);
可能是因为对于大向量来说,这将会非常缓慢。
在包含1000个对象的向量上执行pop_front()
需要999次operator=()
调用。
erase(v.begin())
慢。这是因为向量在开头插入没有特殊属性,与在末尾插入(或弹出)相反。 - orlpVector看起来像是一个栈容器,我们有一个堆栈来存储数据。
因此我们只需要使用pop_back
而不是pop_front
。
如果你想要pop_front
,std::list
可能是更好的选择。因为它是一个双向队列结构。