是否可以使用带有容器的移动操作的类型?

Adr*_*ian 11 c++ stl c++11 c++14 stdmove

在解释与同事对对象的移动操作时,我基本上说移动操作不应该在容器中抛出异常,因为如果移动操作失败,则无法可靠地恢复原始对象.考虑到这一点,我想知道这是不是正确的,并且如果一个移动操作确实抛出,它可以将原始对象恢复到它的原始状态.

这样做的原因是,如果一个对象可以抛出,那么它将不会因为复制或将包含的对象从旧地址移动到新地址而抛出,而是在无法获取资源时抛出.所以所有的原始信息都应该存在.如果是这种情况,那么编译器是否应该无法反转它为重建原始对象所做的操作?

操作可能是一种方式,比如移动一个整数,但在这种情况下它可能只是终止应用程序,也许如果开发人员想要避免单向操作可以使用交换方法.

这只能在默认移动运算符上实现,就像有任何其他逻辑一样,编译器可能很难进行反向部分变换.

我是否过于简化了事情?有没有我遗漏的东西,如果没有非投掷移动构造函数/运算符,容器不会移动对象?

Nic*_*las 10

你可以使用在容器中投掷移动的类型vector,可以移动它们的元素.但是,这种容器不会使用抛掷移动操作.

假设你有vector10个投掷移动元素.并vector需要调整自己.所以它将5个对象移动到新内存,但是第6个抛出.嗯,那没关系; 构造失败,所以假设第6个对象的值很好.也就是说,无论该类型的异常保证是什么,都将是事情的运作方式.

但是,由于一个对象的移动失败,vector需要将最后5个对象移回第一个数组,因为vector它试图提供强大的异常保证.这是一个问题,因为撤回本身就会失败.

当修复故障本身的过程失败时,C++通常没有有效的答案.你可以在例外中看到; 您不能从由于异常失败而在展开过程中调用的析构函数中发出异常.std::terminate在这种情况下发生.

同样的道理vector.如果搬回失败,vector没有明智的答案.因此,如果vector不能保证恢复其先前的阵列状态noexcept,那么它将使用复制,因为这可以提供该保证.