C++ 快速删除向量类型

C++ 快速删除向量类型,c++,vector,stdvector,C++,Vector,Stdvector,我的问题是如何优化vector::erase函数 既然我们知道向量是一个连续的内存块,也知道容器中每个元素的大小,为什么vector v的erase(v.begin())方法仍然调用v中所有元素的析构函数?它能进行字节转换吗 例如: 说你有 //compiled with g++ 4.7 #include<iostream> using namespace std; class barebone{ public: ~barebone(){ cout << "1

我的问题是如何优化
vector::erase
函数

既然我们知道向量是一个连续的内存块,也知道容器中每个元素的大小,为什么
vector v
erase(v.begin())
方法仍然调用
v
中所有元素的析构函数?它能进行字节转换吗

例如: 说你有

//compiled with g++ 4.7
#include<iostream>
using namespace std;
class barebone{
public:
  ~barebone(){
    cout << "1" << endl;
  }
};

int main(){
    vector<barebone> x(5);
    x.erase(x.begin());
    cout << "done" << endl;
}
//用g++4.7编译
#包括
使用名称空间std;
赤骨级{
公众:
~barebone(){

cout应该只为被擦除的元素调用析构函数;如果您看到它为其他元素调用,那么您的
向量
实现不符合C++11 23.3.6.5 指定

复杂性:T的析构函数被称为元素数的次数 已擦除,但T的移动赋值运算符的调用次数等于 删除元素后向量中的元素

较旧的标准规定了类似的行为,但使用的是复制而不是移动分配


您的示例显示了
1
五次,因为当向量在
main
末尾被销毁时,会调用剩余的析构函数。如果在调用
erase
后立即输出一些内容,则可以更清楚地看到这一点析构函数只应为元素调用正在被擦除;如果您看到它被其他人调用,那么您的
向量
实现不一致。C++11 23.3.6.5
指定

复杂性:T的析构函数被称为元素数的次数 已擦除,但T的移动赋值运算符的调用次数等于 删除元素后向量中的元素

较旧的标准规定了类似的行为,但使用的是复制而不是移动分配


您的示例显示了
1
五次,因为当向量在
main
末尾被销毁时,会调用剩余的析构函数。如果在调用
erase
后立即输出一些内容,您可以更清楚地看到这一点。我不买它。我编写了一个测试程序,在擦除之后调用析构函数d只有一次。我建议你也这样做,自己看看

#include <iostream>
#include <vector>

using namespace std;

class TestObject
{
    public:
    static int counter;
    TestObject()  { std::cout << "constructed!" << std::endl; }
    ~TestObject() { std::cout << "destructed!" << std::endl; counter++;}
};

int TestObject::counter = 0;

int main()
{
   std::vector<TestObject> to(5);
   to.erase(to.begin());
   std::cout << "destructed " << TestObject::counter << " times" << std::endl;

   to.push_back(TestObject());

   return 0;
}
#包括
#包括
使用名称空间std;
类TestObject
{
公众:
静态整数计数器;

TestObject(){std::cout我不买它。我写了一个测试程序,在擦除之后,析构函数只被调用一次。我建议你也这样做,自己看看

#include <iostream>
#include <vector>

using namespace std;

class TestObject
{
    public:
    static int counter;
    TestObject()  { std::cout << "constructed!" << std::endl; }
    ~TestObject() { std::cout << "destructed!" << std::endl; counter++;}
};

int TestObject::counter = 0;

int main()
{
   std::vector<TestObject> to(5);
   to.erase(to.begin());
   std::cout << "destructed " << TestObject::counter << " times" << std::endl;

   to.push_back(TestObject());

   return 0;
}
#包括
#包括
使用名称空间std;
类TestObject
{
公众:
静态整数计数器;

TestObject(){std::cout关于非平凡的析构函数呢?在这种情况下,您只调用第一个元素的析构函数。但对其余元素执行字节移位。字节移位如何恢复内存?对不起,我不明白。此代码不一定调用这些元素的析构函数。只有在调整大小时才会调用析构函数g、 这里不需要调整大小。当不调整大小时,这将调用前四个元素的复制/移动赋值运算符,以及最后一个元素的析构函数。非平凡析构函数呢?在这种情况下,您只调用第一个元素的析构函数。但对其余元素执行按字节移位。按字节移位如何ft recover memory?对不起,我没有听清楚。此代码不一定会调用这些元素的析构函数。只有在调整大小时才会调用析构函数,并且这里不需要调整大小。在不调整大小时,这将调用前四个元素的复制/移动赋值运算符,以及最后一个元素的析构函数。对于C++03,It dep但在赋值运算符上结束。如果使用
运算符=(Foo-other)
而不是
const-Foo&other
,临时文件每次都会被销毁。在标题为
的线程中,建议使用
Foo-other
而不是
const-Foo&other
来进行一些优化或w/e.。无论如何,+1来自我。我认为它必须销毁所有元素对于C++03,这取决于赋值运算符。如果使用
运算符=(Foo-other)
而不是
const-Foo&other
,临时文件每次都会被销毁。在标题为
的线程中,建议使用
Foo-other
而不是
const-Foo&other
来进行一些优化或w/e.。无论如何,+1来自我。我认为它必须销毁所有元素什么。。