Wednesday 22 November 2017

c++ - How to use an iterator?

itemprop="text">

I'm trying to calculate the distance
between two points. The two points I stored in a vector in C++: (0,0) and
(1,1).



I'm supposed to get results
as



0

1.4
1.4
0


But
the actual result that I got
is



0
1
-1

0


I
think there's something wrong with the way I use iterator in vector.
How can I
fix this problem?



I posted the code
below.



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 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
::iterator ii;
vector ::iterator jj;
for
(ii = po.begin(); ii != po.end(); ii++)

{
for (jj =
po.begin(); jj != po.end(); jj++)
{
cout << distance(ii,jj)
<< " ";
}
}
return
0;
}

class="post-text" itemprop="text">
class="normal">Answer





That your code compiles at all is
probably because you have a using namespace std somewhere.
(Otherwise vector would have to be
std::vector.) href="https://stackoverflow.com/questions/2879555/c-stl-how-to-write-wrappers-for-cout-cerr-cin-and-endl/2880136#2880136">That's
something I would advise against
and you have just provided a
good case why:
By accident, your call picks up
std::distance(), which takes two iterators and calculates the
distance between them. Remove the using directive and prefix all standard library types
with std:: and the compiler will tell you that you tried to
pass a vector ::iterator where a
point* was required.



To get a pointer to an object an iterator
points to, you'd have to dereference the iterator - which gives a reference to the
object - and take the address of the result: &*ii. />(Note that a pointer would perfectly fulfill all requirements for a
std::vector iterator and some earlier implementations of the
standard library indeed used pointers for that, which allowed you to treat
std::vector iterators as pointers. But modern implementations
use a special iterator class for that. I suppose the reason is that using a class allows
overloading functions for pointers and iterators. Also, using pointers as
std::vector iterators encourages mixing pointers and iterators,
which will prevent the code to compile when you change your container.)



But rather than doing this, I suggest you
change your function so that it takes references instead (see href="https://stackoverflow.com/questions/2139224/2139254#2139254">this
answer for why that's a good idea anyway.) :



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));

}


Note
that the points are taken by const references. This indicates
to the caller that the function won't change the points it is passed.



Then you can call it like this:
distance(*ii,*jj).



/>

On a side note, this




typedef struct point
{
float x;
float y;
}
point;


is a C-ism
unnecessary in C++. Just spell it



struct point
{

float x;
float
y;
};


That
would make problems if this struct definition ever was to parse
from a C compiler (the code would have to refer to struct point
then, not simply point), but I guess
std::vector and the like would be far more of a challenge to a
C compiler anyway.


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...