例如,通过删除第一个和最后一个值,我想将向量转换为该向量的子范围。在这种情况下使用assign成员函数是否有效?
std::vector<int> data = {1, 2, 3, 4};
data.assign(data.begin() + 1, data.end() - 1);
// data is hopefully {2, 3}
对容器元素的所有迭代器,指针和引用均无效。过去的迭代器也无效。
但是,直到end of assign,这种失效似乎才发生。
为了安全起见,我可以遵循以下内容,但似乎更为冗长:
std::vector<int> data = {1, 2, 3, 4};
data = std::vector<int>{data.begin() + 1, data.end() - 1};
// data is now {2, 3}
您的链接所引用的__invalidate_all_iterators
函数仅仅是调试工具。它不会“导致”迭代器失效;它不会导致迭代器失效。它有效地报告了迭代器已被先前的操作无效。可能是该调试工具可能未捕获到由该分配引起的错误。
assign
的前提条件是迭代器不能位于同一容器中。违反先决条件会导致不确定的行为。
标准报价(最新草案):
[sequence.reqmts]
a.assign(i,j)
期望:T是Cpp17Emplace,可从* i构造为X,并从* i分配。对于矢量,如果迭代器不满足正向迭代器要求([forward.iterators]),则T也是Cpp17MoveInsertable,可以转换为X。i和j都不是对a的迭代器。
您的安全替代方法是正确的。