由于 C++11 引入了基于范围的 for 循环(c++11 中的基于范围的 for),那么在整数范围内表示循环的最简洁方法是什么?
代替
for (int i=0; i<n; ++i)
我想写一些类似的东西
for (int i : range(0,n))
新标准是否支持这种类型的东西?
更新:本文描述了如何在 C++11 中实现范围生成器:Generator in C++
由于 C++11 引入了基于范围的 for 循环(c++11 中的基于范围的 for),那么在整数范围内表示循环的最简洁方法是什么?
代替
for (int i=0; i<n; ++i)
我想写一些类似的东西
for (int i : range(0,n))
新标准是否支持这种类型的东西?
更新:本文描述了如何在 C++11 中实现范围生成器:Generator in C++
虽然 C++11 不提供,但您可以编写自己的视图或使用 boost 中的视图:
#include <boost/range/irange.hpp>
#include <iostream>
int main(int argc, char **argv)
{
for (auto i : boost::irange(1, 10))
std::cout << i << "\n";
}
此外,Boost.Range
包含一些更有趣的范围,您会发现它们与新for
循环相结合非常有用。例如,您可以获得反向视图。
最整洁的方法仍然是:
for (int i=0; i<n; ++i)
我想你可以做到这一点,但我不会说它那么整洁:
#include <iostream>
int main()
{
for ( auto i : { 1,2,3,4,5 } )
{
std::cout<<i<<std::endl;
}
}
随着C++20
我们将有范围。您可以通过从其作者 Eric Niebler 下载最新的稳定版本来尝试它们,从他的 github或转到Wandbox。您感兴趣的是ranges::views::iota
,这使得这段代码合法:
#include <range/v3/all.hpp>
#include <iostream>
int main() {
using namespace ranges;
for (int i : views::iota(1, 10)) {
std::cout << i << ' ';
}
}
这种方法的优点在于view
s 是惰性的。这意味着即使views::iota
表示从1
到独占的范围,在某一点上也10
不会超过该范围中的一个。int
这些元素是按需生成的。
如果您不介意以相反的顺序执行循环,则可以替换
for (int i=0; i<n; ++i)
用更简单的
for (int i=n; i--;)
根据您对整数所做的事情,还要考虑<numeric>
标题,特别
std::iota
是结合std::transform
并std::fill
根据情况而定。
好吧,我真的很喜欢这里提供的解决方案(对不起,它没有翻译成英文):
#define FOR(I,UPPERBND) for(int I = 0; I<int(UPPERBND); ++I)
主要思想是这样描述的:当我们谈论简单的迭代索引循环时,我们不需要考虑它。但是,当我们使用 for(;;) 构造时,总是有三个步骤:初始化、结束条件检查、迭代。对于像 i:[0,n) 这样简单的循环,这有点过头了。我喜欢这个想法,我们想以简单的方式编写简单的东西。当你看到 FOR(i,N) - 你就知道,没有什么特别的。当您看到 for(;;) 构造时 - 您必须更加小心并查看它的所有三个部分。只是那篇文章的一个例子:
for (int iter=0; iter<nb_iter; iter++) { // some iterative computation
for (int c=0; c<mesh.cells.nb(); c++) // loop through all tetrahedra
for (int lv0=0; lv0<4; lv0++) // for every pair of
for (int lv1 = lv0+1; lv1<4; lv1++) // vertices in the tet
for (int d=0; d<3; d++) { // do stuff for each of 3 dimensions
nlRowScaling(weight);
nlBegin(NL_ROW);
nlCoefficient(mesh.cells.vertex(c, lv0)*3 + d, 1);
nlCoefficient(mesh.cells.vertex(c, lv1)*3 + d, -1);
nlEnd(NL_ROW);
}
[...]
}
成为一个:
FOR(iter, nb_iter) {
FOR(c, mesh.cells.nb())
FOR(lv0, 4)
for (int lv1 = lv0+1; lv1<4; lv1++)
FOR(d, 3) {
nlRowScaling(weight);
nlBegin(NL_ROW);
nlCoefficient(mesh.cells.vertex(c, lv0)*3 + d, 1);
nlCoefficient(mesh.cells.vertex(c, lv1)*3 + d, -1);
nlEnd(NL_ROW);
}
[...]
}
你看,你应该把注意力集中在哪里。