你能用C ++破坏和重建一个向量的元素吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你能用C ++破坏和重建一个向量的元素吗?相关的知识,希望对你有一定的参考价值。
从外部破坏和构造向量元素是否合法?假设您将一组元素保留在您开始构建的状态中,当然?并假设不做任何明显愚蠢的事情,比如在相同的元素上调用析构函数两次,或类似的。
抛开异常,我想象的是以下内容:
int main ()
{
std::vector<std::string> v (10, "Hello");
v [2].std::string::~string ();
new (&v [2]) std::string ("World");
}
或者这样的事情会是UB吗?其他标准容器呢?
答案
这是完全有效的,就像你总是可以显式地调用任何对象的析构函数一样。但是,它可能是愚蠢的。在摧毁和复活元素之间,向量处于无法被破坏的状态。如果由于某种原因调用了析构函数,则会获得UB。这特别危险,因为你可能不会一个接一个地做这两个步骤。
现在,你不只是为了好玩而这样做。如果你想要,例如要擦除一个元素,你可以创建一个临时的,与元素交换然后销毁临时元素。这样,你就不会有这个窗口,你不能破坏矢量。此外,这种方法甚至适用于像std::string
元素这样的非常重要的情况,也适用于更复杂的矢量元素。
另一答案
你可以这样做,但是矢量中的插槽在破坏和重建之间是无效的。如果由于某种原因(可能是异常),在重构之前调用向量的DTOR,接着会出现未定义的行为。
以下是一个更安全的替代方案。任何合理质量的std :: string实现都将构造一个带有“World”的新std :: string,然后使用rvalue-assignment运算符(move-semantics)将其放入向量槽。执行此任务期间没有任何周期受到伤害。
#include <string>
#include <iostream>
int main()
{
v[2] ="World";
std::cout << v[2] << std::endl;
return 0;
}
以上是关于你能用C ++破坏和重建一个向量的元素吗?的主要内容,如果未能解决你的问题,请参考以下文章