【问题标题】:Exception guarantees when moving object into std::vector将对象移动到 std::vector 时的异常保证
【发布时间】:2019-08-09 18:31:52
【问题描述】:

如果在将对象移动到 std::vector 时内存分配失败,并抛出 bad_alloc,std::vector 是否保证从对象移出的对象不变/仍然有效?

例如:

std::string str = "Hello, World!";
std::vector<std::string> vec;

vec.emplace_back(std::move(str));
/* Is str still valid and unaltered if the previous line throws? */

【问题讨论】:

    标签: c++ stdvector exception-safety


    【解决方案1】:

    [container.requirements.general]/11.2 对此进行了介绍

    如果 push_­back()push_­front()emplace_­back()emplace_­front() 函数引发异常,则该函数无效。

    因此,如果发生异常,您将不会从对象移动。

    这仅涵盖向量抛出的情况。我们需要查看[vector.modifiers]/1,看看如果移动构造函数本身抛出了会发生什么:

    如果在末尾插入单个元素时引发异常并且TCpp17CopyInsertableis_­nothrow_­move_­constructible_­v&lt;T&gt;true,则没有效果。 否则,如果非Cpp17CopyInsertable T 的移动构造函数抛出异常,则效果未指定。

    强调我的

    在这种情况下,行为是未指定的。


    在您的情况下,std::string 有一个 noexcpet 移动构造函数,因此如果抛出异常,您将拥有一个有效的对象。

    【讨论】:

    • hm 我的印象是除非它是 noexcept 否则不会使用 move ctor(或者 impl 想出了其他不会引发异常的方法)
    • @LightnessRacesinOrbit 仅在增长向量时。它总是会调用右值的 push/emplace_back 移动。
    • 是的,标准不知道那里的结果似乎是公平的。只有写了 move ctor 的 OP 才能知道扔掉它的效果。不属于 q :D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多