For 循环从范围的中间开始循环
For Loop That Starts At Middle Of Range And Loops Around
是否可以有一个 for 循环,它从一个范围的中间开始,然后循环到范围的开头并继续直到循环遍历整个范围?例如,假设我们的范围是 0 到 63,我希望循环从 22 开始,继续循环直到到达 63,然后从 0 开始循环直到到达 21。for 循环是否可行?或者我需要一个 while 循环吗?
我将使用两个循环变量:一个用于计算重复次数,一个用于处理所需的索引。像这样:
for (int i = 0, j = 22; i < 64; ++i, j = (j + 1) % 64)
// do something with j
当然,在实际代码中,您会将幻数 (22, 64) 替换为更清楚地反映所涉及的实际对象的内容。
是的,您可以为此使用基于范围的 for
循环。一个 C++20 STL 示例(using namespace std::ranges
):
constexpr void foo(auto&& range) {
auto middle = range.begin() + 22;
auto parts = {subrange{middle, range.end()}, subrange{range.begin(), middle}};
for (auto&& elem: parts | views::join) bar(elem);
}
也许有更好看的方法/库。使用适当的 API,它应该类似于
constexpr void foo(auto&& range) {
for (auto&& elem: range | drop(22) | chain(range | take(22))) bar(elem);
}
编辑: 几乎相同的“正确的 API”可以在 ranges::v3
::view
中找到(concat
这里是我想象的 chain
):
的“unpipable”版本
constexpr void foo(auto&& range) {
for (auto&& elem: concat(range | drop(22), range | take(22))) bar(elem);
}
是的,例如:
for( int i = 22, max = 63, end = i-1 ; i!=-1 ; i=i==end?-1:i==max?0:i+1 )
{
// do something with i
}
是否可以有一个 for 循环,它从一个范围的中间开始,然后循环到范围的开头并继续直到循环遍历整个范围?例如,假设我们的范围是 0 到 63,我希望循环从 22 开始,继续循环直到到达 63,然后从 0 开始循环直到到达 21。for 循环是否可行?或者我需要一个 while 循环吗?
我将使用两个循环变量:一个用于计算重复次数,一个用于处理所需的索引。像这样:
for (int i = 0, j = 22; i < 64; ++i, j = (j + 1) % 64)
// do something with j
当然,在实际代码中,您会将幻数 (22, 64) 替换为更清楚地反映所涉及的实际对象的内容。
是的,您可以为此使用基于范围的 for
循环。一个 C++20 STL 示例(using namespace std::ranges
):
constexpr void foo(auto&& range) {
auto middle = range.begin() + 22;
auto parts = {subrange{middle, range.end()}, subrange{range.begin(), middle}};
for (auto&& elem: parts | views::join) bar(elem);
}
也许有更好看的方法/库。使用适当的 API,它应该类似于
constexpr void foo(auto&& range) {
for (auto&& elem: range | drop(22) | chain(range | take(22))) bar(elem);
}
编辑: 几乎相同的“正确的 API”可以在 ranges::v3
::view
中找到(concat
这里是我想象的 chain
):
constexpr void foo(auto&& range) {
for (auto&& elem: concat(range | drop(22), range | take(22))) bar(elem);
}
是的,例如:
for( int i = 22, max = 63, end = i-1 ; i!=-1 ; i=i==end?-1:i==max?0:i+1 )
{
// do something with i
}