71 c++ pointers iterator vector using-statement
我正在计算两点之间的距离.我用C++中的向量存储的两点:(0,0)和(1,1).
我应该得到结果
0
1.4
1.4
0
Run Code Online (Sandbox Code Playgroud)
但我得到的实际结果是
0
1
-1
0
Run Code Online (Sandbox Code Playgroud)
我认为在向量中使用迭代器的方式有问题.我该如何解决这个问题?
我发布了以下代码.
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;
}
Run Code Online (Sandbox Code Playgroud)
sbi*_*sbi 190
你的代码完全编译可能是因为你有一个using namespace std地方.(否则vector必须是std::vector.)这是我建议反对的,你刚刚提供了一个很好的案例原因:
不小心,你的电话接听std::distance(),需要两个迭代器并计算它们之间的距离.删除using指令与前缀的所有标准库类型std::,编译器会告诉你,你想传递一个vector <point>::iterator地方一个point*是必需的.
要获得指向迭代器指向的对象的指针,您必须取消引用迭代器 - 它提供对象的引用 - 并获取结果的地址:&*ii.
(注意,指针完全满足std::vector迭代器的所有要求,标准库的一些早期实现确实使用了指针,这允许你将std::vector迭代器视为指针.但现代实现使用一个特殊的迭代器类.我想原因是使用类允许重载指针和迭代器的函数.另外,使用指针作为std::vector迭代器会鼓励混合指针和迭代器,这会阻止代码在更改容器时编译.)
但不是这样做,我建议你改变你的功能,以便它需要引用(看看这个答案,为什么这是一个好主意.):
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));
}
Run Code Online (Sandbox Code Playgroud)
请注意,这些点是通过const引用获取的.这向调用者表明该函数不会改变它传递的点.
然后你就可以这样称呼:distance(*ii,*jj).
在旁注,这
typedef struct point {
float x;
float y;
} point;
Run Code Online (Sandbox Code Playgroud)
在C++中是不必要的C-ism.拼这个吧
struct point {
float x;
float y;
};
Run Code Online (Sandbox Code Playgroud)
如果这个struct定义是从C编译器解析的话会产生问题(代码必须引用struct point当时的,而不是简单的point),但我猜想std::vector等等对C编译器来说更是一个挑战.
Jor*_*ans 21
巧合的是,你实际上使用的是内置的STL函数"distance",它计算迭代器之间的距离,而不是调用你自己的距离函数.您需要"取消引用"迭代器以获取包含的对象.
cout << distance(&(*ii), &(*jj)) << " ";
Run Code Online (Sandbox Code Playgroud)
从上面的语法中可以看出,"迭代器"与广义的"指针"非常相似.迭代器不能直接用作"您的"对象类型.事实上,迭代器与指针非常相似,因此许多在迭代器上运行的标准算法也可以在指针上正常工作.
正如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) << " ";
Run Code Online (Sandbox Code Playgroud)
你可以做几件事:
使该distance()函数接受point对象的引用.这实际上只是为了在调用distance()函数时使事情更具可读性:
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));
}
Run Code Online (Sandbox Code Playgroud)在调用时取消引用迭代器,distance()以便传递point对象:
distance( *ii, *jj)
Run Code Online (Sandbox Code Playgroud)如果不更改distance()函数的接口,则可能必须使用以下内容调用它以获取适当的指针:
distance( &*ii, &*jj)
Run Code Online (Sandbox Code Playgroud)