dfr*_*ese 8 c++ undefined-behavior
我想将向量转换为该向量的子范围,例如通过删除第一个和最后一个值。在这种情况下使用assign成员函数是否有效?
std::vector<int> data = {1, 2, 3, 4};
data.assign(data.begin() + 1, data.end() - 1);
// data is hopefully {2, 3}
Run Code Online (Sandbox Code Playgroud)
对容器元素的所有迭代器,指针和引用均无效。过去的迭代器也无效。
但是,直到分配结束,这种无效似乎才发生。
为了安全起见,我可以采用以下内容,但似乎比较冗长:
std::vector<int> data = {1, 2, 3, 4};
data = std::vector<int>{data.begin() + 1, data.end() - 1};
// data is now {2, 3}
Run Code Online (Sandbox Code Playgroud)
eer*_*ika 11
__invalidate_all_iterators您的链接所引用的功能仅仅是调试工具。它不会“导致”迭代器失效;它不会导致迭代器失效。它有效地报告了迭代器已被先前的操作无效。可能是该调试工具可能未捕获到由该分配引起的错误。
前提条件是assign迭代器不能位于同一容器中。违反先决条件会导致不确定的行为。
标准报价(最新草案):
[sequence.reqmts]
a.assign(i,j)期望:T是Cpp17Emplace,可从* i构造为X,并从* i分配。对于向量,如果迭代器不满足正向迭代器要求([forward.iterators]),则T也是Cpp17MoveInsertable,可以转换为X。i 和j都不是a的迭代器。
您的安全替代方法是正确的。
如果您要避免重新分配(请记住将剩下未使用的空间),并且要避免复制(这对复杂类型很重要,对无关紧要int),那么以下操作应该很有效:
int begin_offset = 1;
int end_offset = 1;
if (begin_offset)
std::move(data.begin() + begin_offset, data.end() - end_offset, data.begin());
data.erase(data.end() - end_offset - begin_offset, data.end());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |