如何在重复循环中循环遍历 std::vector
How to loop through an std::vector in repeating cycles
我正在使用 std::vector
和 C++
来存储一些项目并稍后检索它们。以下是我如何遍历向量。
std::vector<some_object> some_vector;
some_vector.resize(10);
for (auto it = some_vector.begin(); it != some_vector.end(); ++it) {
int current_it_index = std::distance(some_vector.begin(), it);
}
我需要每次迭代的索引。因此,如上所示,每次迭代都获取它。
上面的循环 运行良好 但我 想无限循环遍历向量 。我该怎么做?
现在,我明白了问题来了,如果让 运行 重复循环,如何停止 运行ning 循环。我正在考虑使用 std::atomic<bool>
作为变量来发出信号并跳出循环,这应该能很好地工作?
PS: 请注意,我已将 std::vector
作为示例容器来解释问题。如果建议的解决方案也适用于 std::array
或其他容器,那就太好了。
遍历元素为 2 次幂的数组的一个常见技巧是简单地遍历一个计数器并使用掩码操作。
size_t counter = 0;
const size_t mask = some_vector.size() - 1U;
while (!quit) {
size_t i = counter++ & mask;
do_something(some_vector[i]);
}
如果数组不是 2 的幂,您可以执行模运算而不是屏蔽一个空闲的 运行 计数器。
size_t i = 0;
const size_t n = some_vector.size();
while (!quit) {
do_something(some_vector[i++]);
i %= n;
}
如果您使用的是非随机访问容器,并且需要迭代器和索引,那么您可以实现两个循环。这将避免在非随机访问迭代器上计算 distance
的开销。
for (;;) {
size_t idx = 0;
for (auto it = some_container.begin();
it != some_container.end();
++it) {
do_something(it, idx++);
}
如果我没理解错的话,你想要的是当你到达容器的最后一个元素时,你只需再次跳转到容器的开头。我们可以很容易地编写代码:
auto first = std::begin(c);
const auto last = std::end(c);
std::size_t idx = 0;
while (!should_exit()) {
do_something(idx);
++idx;
if (++first == last) { // reset
idx = 0;
first = std::begin(c);
}
}
这应该适用于任何 STL 样式的容器。拥有迭代器和索引可能是不必要的,但这是一个 KISS 解决方案,适用于非随机访问容器,如 std::list
以及 vector/array.
std::vector<some_object> some_vector;
some_vector.resize(10);
bool quit = false;
while (!quit) {
for (auto& e:some_vector) {
if (quit) break;
std::size_t i = std::addressof(e)-some_vector.data();
// ...
}
}
我正在使用 std::vector
和 C++
来存储一些项目并稍后检索它们。以下是我如何遍历向量。
std::vector<some_object> some_vector;
some_vector.resize(10);
for (auto it = some_vector.begin(); it != some_vector.end(); ++it) {
int current_it_index = std::distance(some_vector.begin(), it);
}
我需要每次迭代的索引。因此,如上所示,每次迭代都获取它。
上面的循环 运行良好 但我 想无限循环遍历向量 。我该怎么做?
现在,我明白了问题来了,如果让 运行 重复循环,如何停止 运行ning 循环。我正在考虑使用 std::atomic<bool>
作为变量来发出信号并跳出循环,这应该能很好地工作?
PS: 请注意,我已将 std::vector
作为示例容器来解释问题。如果建议的解决方案也适用于 std::array
或其他容器,那就太好了。
遍历元素为 2 次幂的数组的一个常见技巧是简单地遍历一个计数器并使用掩码操作。
size_t counter = 0;
const size_t mask = some_vector.size() - 1U;
while (!quit) {
size_t i = counter++ & mask;
do_something(some_vector[i]);
}
如果数组不是 2 的幂,您可以执行模运算而不是屏蔽一个空闲的 运行 计数器。
size_t i = 0;
const size_t n = some_vector.size();
while (!quit) {
do_something(some_vector[i++]);
i %= n;
}
如果您使用的是非随机访问容器,并且需要迭代器和索引,那么您可以实现两个循环。这将避免在非随机访问迭代器上计算 distance
的开销。
for (;;) {
size_t idx = 0;
for (auto it = some_container.begin();
it != some_container.end();
++it) {
do_something(it, idx++);
}
如果我没理解错的话,你想要的是当你到达容器的最后一个元素时,你只需再次跳转到容器的开头。我们可以很容易地编写代码:
auto first = std::begin(c);
const auto last = std::end(c);
std::size_t idx = 0;
while (!should_exit()) {
do_something(idx);
++idx;
if (++first == last) { // reset
idx = 0;
first = std::begin(c);
}
}
这应该适用于任何 STL 样式的容器。拥有迭代器和索引可能是不必要的,但这是一个 KISS 解决方案,适用于非随机访问容器,如 std::list
以及 vector/array.
std::vector<some_object> some_vector;
some_vector.resize(10);
bool quit = false;
while (!quit) {
for (auto& e:some_vector) {
if (quit) break;
std::size_t i = std::addressof(e)-some_vector.data();
// ...
}
}