(对于具体的编译器/平台上下文,在x86_64上使用GCC 4.7和Ubuntu 12.04)
给出一些函数f:
void f(int x, int y);
int nx = ...;
int ny = ...;
从(0,0)到(nx,ny)迭代每个值(x,y)的一种方法是:
for (int x = 0; x < nx; x++)
for (int y = 0; y < ny; y++)
f(x,y);
让这个编译成一些生成的代码Q1。
我们将编写一个函数g:
for (auto it : g(Z))
f(it.x, it.y);
编译成代码Q2。
是否有可能写出这样的Q2,Q2与Q1一样有效?如果有,怎么样?如果没有,我们能得到的最接近的是什么?
您可以将自动更改为自动&amp;或汽车&amp;&amp;如果它有帮助。
如果有帮助,您也可以将it.x更改为it.x(),it.y更改为it.y()。
(回想一下,基于范围的扩展只是一种类似迭代器的类型:C++11: The range-based for statement: "range-init" lifetime?)
答案 0 :(得分:3)
是否有可能写出这样的Q2,Q2与Q1一样有效?如果有,怎么样?如果没有,我们能得到的最接近的是什么?
当然可能,您只需要定义以与for
循环相同的方式递增的迭代器。从头到尾:
class matrix_iterator
{
public:
...
matrix_iterator& operator++()
{
if( ++y >= ny )
{
++x;
y = 0;
}
return *this;
}
private:
int nx, ny;
int x, y;
};
答案 1 :(得分:2)
此代码具有您需要的功能。我还没有验证它,但我怀疑它会产生与原始循环几乎相同的机器代码(在优化的编译中)。
struct iter {
int x, y, ny;
iter(int x, int y, int ny) : x(x), y(y), ny(ny) {}
iter &operator++ () {
if (++y >= ny)
{
y = 0;
++x;
}
return *this;
}
bool operator != (iter const &rhs) const {
return y != rhs.y || x != rhs.x;
}
};
struct container {
iter endit;
container(int nx, int ny) : endit(nx, ny, ny) {}
iter begin() const { return iter(0,0,endit.ny); }
iter const &end() const { return endit; }
};
container g(Z const &z) { return container(z.nx, z.ny); }
for ( auto it : g(Z) )
f(it.x, it.y);