我的问题是关于优化vector::erase
功能。
由于我们知道向量是一个连续的内存块,并且也知道容器中每个元素的大小,为什么vector<myclass> v
的{{1}}方法仍然会调用所有erase(v.begin())
中元素的析构函数?它可以进行逐字节移位吗?
实施例: 说你有
v
这将为容器中的每个元素调用析构函数(5次)。这将显示5个。逐字节移位将更快并且只调用析构函数一次
编辑:从回复erase()调用析构函数一次输出
1 DONE 1 1 1 1
答案 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次。