【发布时间】:2021-10-28 15:33:22
【问题描述】:
我已经通过 SO 进行了搜索,并且对以下内容是否安全有疑问。
考虑这个向量:
std::vector<std::pair<const key, value>> vec;
想象一下,我想将i 位置的元素与最后一个元素交换并弹出。
暂时忽略这样一个事实,即如果出现问题,向量可能处于不安全状态。我完全知道这一点,但问题更多的是关于周围的其他操作。
由于我不能交换这两个元素,我很想这样做:
auto *elem = std::addressof(vec[i]);
std::destroy_at(elem);
std::construct(alloc, elem, std::move(vec.back());
vec.pop_back();
同样,我们在第 2 行和第 3 行之间处于不安全状态,但让我们忽略它。
我很想知道销毁和重建位置 i 的元素对于所有 i 是否是安全。
据我了解,我对此有几个疑问:
-
当
i为0 时,我们有点在使用与向量本身存储的相同的initial 指针。因此,我想知道在这种情况下我们是否应该将向量强制为std::launder它(是的,这是不可能的,我只是在这里输入 in theory 字段)。 -
由于这对有一个 const 键,我猜破坏和重建它可能会导致 UB。不过,我对此不太确定,只是我的直觉。
【问题讨论】:
-
一个问题是,如果您尝试删除最后一个元素(即
i == vec.size() - 1),它将无法正常工作。您将销毁最后一个元素,然后尝试从其自身构造它。 -
你真的需要
Key成为const吗? vector of const doesn't work that well -
@1201ProgramAlarm 是的,这只是一个例子,假设有一个
if可以跳过这个案例。 -
@AlanBirtles 我没有,但我为这个问题做。 :)
-
如果第 2 行或第 3 行中的任何一个抛出,您将被水洗。现在它的析构函数抛出的错误形式(尽管它完全有效),并且移动构造函数也可以抛出。无论哪种情况,当向量最终尝试访问已销毁/未创建的元素(通常是自行销毁)时,都会出现问题。
标签: c++ c++17 language-lawyer undefined-behavior