关于c ++:将pop_front实现为std :: vector的快速方法

Fast way to implement pop_front to a std::vector

我正在使用一些使用std :: vector的类和几种实用程序方法。

现在,我需要在其中一个类的每个帧上使用pop_front-push_back方法(但它们都已链接在一起,并且可以一起工作,因此我不能只更改其中一个)。

大多数操作都遍历所有element和push_back操作,因此我为最好的工作应该做的是:派生这些类和实用程序的存储库,对所有内容进行模板化,并使用双端队列或列表。

但这意味着大量的代码重写和大量的测试,这些使我错过了截止日期。

因此,我需要建议将有效的pop_front写入静态大小的向量(大小不会改变)。

我在这里找到了一种方法:

1
2
3
4
5
6
7
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?
}

另一个想法应该是:

1
2
3
4
5
6
7
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());
}

这两种解决方案中最快的是什么? 还有其他解决方案吗?


我期望:

1
2
3
4
5
6
7
template<typename T>
void pop_front(std::vector< T >& vec)
{
    assert(!vec.empty());
    vec.front() = std::move(vec.back());
    vec.pop_back();
}

这样做是最有效的方法,但它不会保持向量中元素的顺序。

如果需要保持vec中其余元素的顺序,则可以执行以下操作:

1
2
3
4
5
6
template<typename T>
void pop_front(std::vector< T >& vec)
{
    assert(!vec.empty());
    vec.erase(vec.begin());
}

这与vec中的元素数量成线性关系,但是这是在不更改数据结构的情况下最好的方法。

这些函数都不会将vector保持恒定大小,因为pop_front操作根据定义将从容器中删除一个元素。


由于pop_front()仅擦除第一个元素,因此直接实现是这样的:

1
2
3
4
5
6
template <typename V>
void pop_front(V & v)
{
    assert(!v.empty());
    v.erase(v.begin());
}

暂时不用担心速度。如果要返回并优化代码,请要求专门的项目时间。


我也有办法...不太好..

这看起来像@ 0xPwn的解决方案,但他第二次没有反转向量。
您可能会理解此代码,所以我不会解释。

1
2
3
4
5
6
7
8
9
#include
#include <vector>
template <typename T>
void pop_front(std::vector< T >& vec){
    std::reverse(vec.begin(),vec.end()); // first becomes last, reverses the vector
    vec.pop_back(); // pop last
    std::reverse(vec.begin(),vec.end()); // reverses it again, so the elements are in the same order as before

}

如果您只是尝试擦除第一个元素,则在函数中使用:

1
2
3
if (my_vector.size()){ //check if there any elements in the vector array
    my_vector.erase(my_vector.begin()); //erase the firs element
}

如果您想模拟整个向量数组的pop front(您希望从头到尾保持弹出每个元素),我建议:

1
2
reverse(my_vector.begin(),my_vector.end());  // reverse the order of the vector array
my_vector.pop_back();   // now just simple pop_back will give you the results