更快删除矢量类型

时间:2014-03-20 17:08:47

标签: c++ vector stdvector

我的问题是关于优化vector::erase功能。

由于我们知道向量是一个连续的内存块,并且也知道容器中每个元素的大小,为什么vector<myclass> v的{​​{1}}方法仍然会调用所有erase(v.begin())中元素的析构函数?它可以进行逐字节移位吗?

实施例: 说你有

v

这将为容器中的每个元素调用析构函数(5次)。这将显示5个。逐字节移位将更快并且只调用析构函数一次

编辑:从回复erase()调用析构函数一次输出

1    DONE    1    1    1    1

2 个答案:

答案 0 :(得分:4)

只应为要删除的元素调用析构函数;如果你看到其他人要求它,那么你的vector实现并不符合要求。 C ++ 11 23.3.6.5 指定

  

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

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

您的示例显示1五次,因为在main末尾销毁向量时会调用剩余的析构函数。如果在调用erase后立即输出内容,您可以更清楚地看到这一点。

答案 1 :(得分:0)

我不买。我写了一个测试程序,擦除后析构函数只调用一次。我建议你做同样的事情并亲自看看。

#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;
}

这是输出。

编译源代码.... $ g ++ -std = c ++ 11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2&gt;&amp; 1

执行程序.... $ demo构建!建造!建造!建造!建造!遭到破坏!破坏1次构建!遭到破坏!遭到破坏!遭到破坏!遭到破坏!遭到破坏!自毁!

显然,析构函数在擦除后执行一次。现在,如果您在自己的示例中将擦除视为最后一个cout,那么您可能认为它被擦除了5次。