为什么C ++ pop_front
中没有std::vector
方法?
答案 0 :(得分:53)
因为std::vector
没有关于在前面插入元素的特定功能,不像其他一些容器。每个容器提供的功能对该容器有意义。
您可能应该使用std::deque
,在前面和后插入显式好。
检查this diagram。
答案 1 :(得分:16)
简单。试试吧:
vec.erase(vec.begin());
答案 2 :(得分:14)
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
};
“begin”提供双重任务作为“指向向量中第一个T的指针”和“指向我们分配的所有内存的指针”。因此,通过简单地增加“开始”就不可能从向量的前面“弹出”元素 - 执行此操作并且您不再需要指向需要释放的内存的指针。那会泄漏记忆。所以“pop_front”需要将所有Ts从向量的背面复制到向量的前面,这相对较慢。所以他们决定将它排除在标准之外。
你想要的是这样的:
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
};
有了这个,你可以通过向前和向后移动“开始”来“pop_front”,而不会忘记以后要释放哪个内存。为什么std :: vector不以这种方式工作?我想这是编写标准的人的品味问题。他们的目标可能是提供最简单的“动态可调整阵列”,我认为他们成功了。
答案 3 :(得分:9)
因为push_back
和pop_back
是仅需要O(1)
计算的向量的特殊操作。任何其他推送或弹出都需要O(n)
。
这不是“bug”或“quirk”,这只是矢量容器的属性。如果您需要快速pop_front,请考虑更改为其他容器。
答案 4 :(得分:2)
可能是因为对于大型载体来说它会非常缓慢。
pop_front()
在包含1000个对象的向量上需要999 operator=()
次调用。
答案 5 :(得分:0)
但是,如果你需要一个pop_front并且不关心向量中的元素索引,你可以种类一个类似的pop_front p>
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
答案 6 :(得分:0)
Vector 看起来像一个堆栈容器,我们有一个堆栈来存储数据。
所以我们只是pop_back
而不是pop_front
。
如果您想pop_front
,std::list
可能是您更好的选择。因为它是一个类似于队列结构的双向结构。
答案 7 :(得分:0)
#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);