如何使用迭代器?
我试图计算两点之间的距离。 我用C ++存储在vector中的两点:(0,0)和(1,1)。
我应该得到的结果
0 1.4 1.4 0
但是我得到的实际结果是
0 1 -1 0
我认为在向量中使用迭代器的方式有些问题。 我该如何解决这个问题?
我发布了下面的代码。
typedef struct point { float x; float y; } point; float distance(point *p1, point *p2) { return sqrt((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y)); } int main() { vector <point> po; point p1; p1.x = 0; p1.y = 0; point p2; p2.x = 1; p2.y = 1; po.push_back(p1); po.push_back(p2); vector <point>::iterator ii; vector <point>::iterator jj; for (ii = po.begin(); ii != po.end(); ii++) { for (jj = po.begin(); jj != po.end(); jj++) { cout << distance(ii,jj) << " "; } } return 0; }
你的代码编译可能是因为你有一个using namespace std
地方。 (否则vector
将不得不是std::vector
。) 这是我build议反对 ,你刚才提供了一个很好的情况,为什么:
意外的是,你的电话会selectstd::distance()
,这需要两个迭代器并计算它们之间的距离。 除去using指令并将所有标准库types作为前缀加上std::
,编译器会告诉你,你已经尝试传递一个vector <point>::iterator
,它需要一个point*
。
为了得到一个指向迭代器指向的对象的指针,你必须对引用该对象的迭代器进行取消引用,并取出结果的地址: &*ii
。
(请注意,一个指针可以很好地满足std::vector
迭代器的所有需求,标准库的一些早期实现也使用了指针,这就允许你将std::vector
迭代器当作指针来处理,但是现代实现使用了一个特殊的我想这是因为使用一个类允许重载函数的指针和迭代器,而且,使用指针作为std::vector
迭代器鼓励混合指针和迭代器,这将阻止代码在您更改容器时进行编译。)
但是我不build议你这样做,所以我build议你改变你的函数,以便引用它(参见这个答案为什么这是一个好主意)。
float distance(const point& p1, const point& p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)); }
请注意,这些点是由const
引用引起的。 这向调用者表明该函数不会改变它传递的点。
那么你可以这样调用它: distance(*ii,*jj)
。
在一个侧面说明,这一点
typedef struct point { float x; float y; } point;
是C ++中不必要的C语言。 只是拼写而已
struct point { float x; float y; };
如果这个struct
定义是从C编译器parsing出来的,那么这会产生问题(代码将不得不引用struct point
,而不是简单的point
),但是我猜std::vector
之类的将会是一个更大的挑战到一个C编译器无论如何。
巧合的是,你实际上使用了一个内置的STL函数“distance”来计算迭代器之间的距离,而不是调用你自己的距离函数。 你需要“取消引用”你的迭代器来获取包含的对象。
cout << distance(&(*ii), &(*jj)) << " ";
从上面的语法可以看出,“迭代器”就像一个广义的“指针”。 迭代器不能直接用作“你的”对象types。 实际上,迭代器与指针很相似,许多在迭代器上运行的标准algorithm也可以很好地处理指针。
正如Sbi指出的:你的距离函数需要指针。 最好重写为const引用,这会使函数更加“规范化”c ++,并使迭代器的引用语法不那么痛苦。
float distance(const point& i_p1, const point& i_p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)); } cout << distance(*ii, *jj) << " ";
你可能会做几件事情:
-
使
distance()
函数参考point
对象。 这只是为了在调用distance()
函数时使事情更加可读:float distance(point const& p1, point const& p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)); }
-
调用
distance()
,请引用您的迭代器,以便传递point
对象:distance( *ii, *jj)
如果你不改变distance()
函数的接口,你可能需要使用类似下面的方法调用它,以获得适当的指针:
distance( &*ii, &*jj)