gpt4 book ai didi

c++ - 无效迭代器的算术

转载 作者:行者123 更新时间:2023-12-01 14:25:16 25 4
gpt4 key购买 nike

在一对 std::vector 迭代器上调用时 std::distance 的行为是否未定义,这些迭代器已通过移动 vector?

对于上下文:我正在为一个类编写复制和移动构造函数,该类具有数据的 vector 和指向该数据的迭代器的 vector。将数据移动到目的地后,我需要转换迭代器 vector 以指向新容器。我想避免在内存中创建中间索引表示。

最佳答案

Is behavior of std::distance undefined when called on a pair of std::vector iterators that have been invalidated by moving the vector?

如果迭代器在移动前有效,移动后它们将保持有效 - 因此您无需使用 std::distance 重新计算它们.

(在下面强调我的)

std::vector::vector

After container move construction, references, pointers, and iterators (other than the end iterator) to other remain valid, but refer to elements that are now in *this.

The current standard makes this guarantee via the blanket statement in [container.requirements.general/12], and a more direct guarantee is under consideration via LWG 2321.

[container.requirements.general/12]指出

Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.

对于移动赋值运算符同样的一揽子声明,这意味着,根据标准,迭代器在移动后保持有效。

LWG 2321 中的当前措辞暗示如果图书馆工作组最终确定标准中的新段落会是什么样子——这似乎很难。 LWG 2321 于 2013 年开放。

no move constructor (or move assignment operator when allocator_traits<allocator_type>::propagate_on_container_move_assignment::value is true) of a container (except for array) invalidates any references, pointers, or iterators referring to the elements of the source container. [Note: The end() iterator does not refer to any element, so it may be invalidated. — end note]

如果这太模糊,你可以使用

[container.requirements.general/11.6]

no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped. [ Note: The end() iterator does not refer to any element, so it may be invalidated. — end note ]

如果迭代器在你之前有效 swap , 它们在 swap 之后 有效.

这是一个使用为 swap 提供的保证的示例类:

#include <vector>

class Foo {
std::vector<int> data{};
std::vector<decltype(data)::iterator> dits{};

public:
Foo() = default;

Foo(const Foo&) = delete; // here, dits would need to be calculated

// A move constructor guaranteed to preserve iterator validity.
Foo(Foo&& rhs) noexcept {
data.swap(rhs.data);
dits.swap(rhs.dits);
}

Foo& operator=(const Foo&) = delete;

// A move assignment operator guaranteed to preserve iterator validity.
Foo& operator=(Foo&& rhs) noexcept {
data.swap(rhs.data);
dits.swap(rhs.dits);
return *this;
}

~Foo() = default;
};

关于c++ - 无效迭代器的算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62404648/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com