Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast way to implement pop_front to a std::vector

I'm using some classes and several utility methods that use std:: vector.

Now I need to use each frame a pop_front - push_back method on one of those classes (but they are all linked, and work together so I can't change only one).

Most of the operations are iterate over all element and push_back operations, so what I should do for the best work is: fork the repository of those classes and utilities, template everything, and use deque or list.

But this means a lot of code rewriting and a lot of testing that will make me miss the deadline.

So I need advice to write an efficient pop_front to a static-size vector (the size will not change).

I've found here a way:

template<typename T> void pop_front(std::vector<T>& vec) {    vec.front() = vec.back();    vec.pop_back();    vec.front() = vec.back();  // but should this work? } 

And another idea should be:

template<typename T> void pop_front(std::vector<T>& vec, already_allocated_vector vec1) {    vec1.clear();    copy(vec.begin(), vec.end()-1, vec1.begin());    copy(vec1.begin(), vec1.end(), vec.begin()); } 

What is the faster of these two solutions? Any other solutions?

like image 265
nkint Avatar asked Feb 25 '12 15:02

nkint


People also ask

Can we do Pop_front in vector?

Implement pop_front operation for a vector in C++ The pop_front operation should remove the first element from the vector and maintain the order of the remaining elements. We know that std::vector only supports push_back and pop_back operations. Both operations run in constant time.

How do you push a front element into a vector?

push_front() function is used to push elements into a list from the front. The new value is inserted into the list at the beginning, before the current first element and the container size is increased by 1. Strong exception guarantee – if an exception is thrown, there are no changes in the container.

Does Pop_back reduce vector size?

No. pop_back() will not shrink the capacity of vector.


2 Answers

I would expect:

template<typename T> void pop_front(std::vector<T>& vec) {     assert(!vec.empty());     vec.front() = std::move(vec.back());     vec.pop_back(); } 

to be the most efficient way of doing this, but it does not maintain the order of the elements in the vector.

If you need to maintain the order of the remaining elements in vec, you can do:

template<typename T> void pop_front(std::vector<T>& vec) {     assert(!vec.empty());     vec.erase(vec.begin()); } 

This will have linear time in the number of elements in vec, but it is the best you can do without changing your data structure.

Neither of these functions will maintain the vector at a constant size, because a pop_front operation will by definition remove an element from a container.

like image 95
Mankarse Avatar answered Sep 21 '22 18:09

Mankarse


Since pop_front() only erases the first element, the direct implementation is this:

template <typename V> void pop_front(V & v) {     assert(!v.empty());     v.erase(v.begin()); } 

Don't worry about speed for now. If you want to go back and optimize code, ask for dedicated project time.

like image 32
Kerrek SB Avatar answered Sep 20 '22 18:09

Kerrek SB