对于以下类别的大小为5的向量,
struct Aclass
{
double x;
std::vector<double> y;
Aclass(){}
Aclass(double x, int ysize): x(x)
{
y.resize(ysize, x * ysize);
}
};
我要删除第二个元素:
void eraseEle()
{
std::vector<Aclass> v(5, Aclass(1, 3));
// Erase the 2nd element
{
std::vector<double>(0).swap(v[2].y);
// Copy the bits from &v[3] ~ &v[5] to &v[2]:
std::memmove(&v[2], &v[3], sizeof(Aclass) * (v.size() - 3));
v.resize(v.size() - 1);
}
// Print
for(int i = 0, iend = v.size(); i < iend; ++i)
{
std::cout << v[i].x << ", " << v[i].y[0] << "\n";
}
}
该方法是非常不标准的。 g++ 4.9.3 -O2
对其进行编译,但是程序始终在std::memmove(...)
处崩溃。是因为STL向量的标头受到某种保护,导致std::memmove()
触发未定义的行为?
谢谢!
答案 0 :(得分:2)
memmove
上的reference指出:
如果对象不是TriviallyCopyable,则未指定memmove的行为,并且可能未定义
STL向量对象不是简单可复制的对象。
如一个评论中所建议,向量成员函数erase
完成了您想要做的事情。
Trivially-copyable对象是以下类的对象:
- 每个副本构造函数都很简单或已删除
- 每个动作的构造函数都是微不足道的或已删除
- 每个副本分配运算符都很简单或已删除
- 每个移动分配运算符都很简单或已删除
- 未删除至少一个复制构造函数,移动构造函数,复制分配运算符或移动分配运算符
- 非删除性毁灭者
这意味着该类没有虚拟函数或虚拟基类。
TriviallyCopyable对象的标量类型和数组也是TriviallyCopyable的,以及此类类型的const限定(但不是volatile限定)版本。