Reputation: 1353
I am trying to construct a loop that will loop over a std::vector
of typedef std::pair<double, double> CFPoint
to produce sets of two points to work on.
if(pointList.size() % 2 == 0)
{
CFPoint first = NULL;
CFPoint second = NULL;
for (std::vector<CFPoint>::const_iterator it = pointList.begin(); it != pointList.end(); ++it)
{
TRACE("APoint: %f, %f\n", it->first, it->second);
if(first == NULL && second == NULL)
{first = it; continue;}
if(first != NULL && second == NULL)
second = it;
if(first != NULL && second != NULL)
{
double transitLen = sqrt( pow((second.first - first.first), 2) + pow((second.second - first.second), 2) );
TRACE("Distance between points: %f\n", transitLen);
first = NULL;
second = NULL;
}
}
}
Reviewing the code you might see that I use = NULL
to signify that a CFPoint
variable is either "ready" or not to be used. My problem is that NULL
is defined as 0
in C++ and I cannot assign 0
to a CFPoint
. There also is no null
keyword in C++.
What might my options be to set my variables as "null" or something like that to achieve the loop above?
Hmm, while I was writing this I had the idea to use pointers in my loop rather than actual variables. You can set a pointer to NULL
. The only issue is when trying to set first
and second
. I've tried to set my first
by doing first = ⁢
but it
is of type iterator
how can I cast it
to CFPoint*
?
Upvotes: 0
Views: 341
Reputation: 5261
The way of structuring the solution seems to be making it more complicated than is probably necessary (Jarod42's solution shows a simpler way). Running with it though you should be able to get it working by using pointList.end()
as your guard value:
if(pointList.size() % 2 == 0)
{
typedef std::vector<CFPoint>::const_iterator ConstPointIterator;
const ConstPointIterator guardValue(pointList.end());
ConstPointIterator first = guardValue;
ConstPointIterator second = guardValue;
for (ConstPointIterator it = pointList.begin(); it != pointList.end(); ++it)
{
TRACE("APoint: %f, %f\n", it->first, it->second);
if(first == guardValue && second == guardValue)
first = it; continue;
if(first != guardValue && second == guardValue)
second = it;
if(first != guardValue && second != guardValue)
{
double transitLen = sqrt( pow((second.first - first.first), 2) + pow((second.second - first.second), 2) );
TRACE("Distance between points: %f\n", transitLen);
first = guardValue;
second = guardValue;
}
}
}
Upvotes: 0
Reputation: 19
Well, your task actually doesn't require a 'null' value for a point, all you need is iterate over pairs of vector elements.
How about this:
if (pointList.size() % 2 == 0)
{
for (std::vector<CFPoint>::const_iterator it = pointList.begin(); it != pointList.end(); it += 2)
{
TRACE("APoint: %f, %f\n", it->first, it->second);
CFPoint first = *it;
CFPoint second = *(it+1);
double transitLen = sqrt(pow((second.first - first.first), 2) + pow((second.second - first.second), 2));
TRACE("Distance between points: %f\n", transitLen);
}
}
Upvotes: 1
Reputation: 217145
You may do something like:
if (pointList.size() % 2 == 0)
{
for (std::size_t i = 0; it != pointList.size(); i += 2)
{
const CFPoint& first = pointList[i];
const CFPoint& second = pointList[i + 1];
TRACE("APoint: %f, %f\n", first.first, first.second);
TRACE("APoint: %f, %f\n", second.first, second.second);
const double transitLen = sqrt(pow((second.first - first.first), 2) + pow((second.second - first.second), 2) );
TRACE("Distance between points: %f\n", transitLen);
}
}
Upvotes: 2
Reputation: 51
it->first and it->second are not pointers. They are both double. So what you are doing here:
if(first == NULL && second == NULL)
is checking if they are equal to 0.
Not even it is a pointer, it is a CFPoint and not CFPoint.
And
CFPoint first = NULL;
CFPoint second = NULL;
Are also not pointers, that is why you cannot set them to NULL. Try:
CFPoint* first = NULL;
CFPoint* second = NULL;
instead, and also use std::vector.
Or do this:
typedef typedef std::pair<double, double>* CFPoint
Upvotes: 0
Reputation: 153909
The obvious problem is that std::pair<double, double>
doesn't
have a sentinal value and the names of its components are
probably not appropriate either. (There's also the problem that
you've named it in a way which suggests that it is part of MFC.)
You should define your type as a class, with provisions for
a null value, if that's what you need. This can be done either
by adding an additional bool
which indicates whether the value
is valid or not, or by doing something tricky with NaNs. (The
first is to be preferred, at least at the start. The second
should be reserved as an optimization measure.)
Upvotes: 0