Std :: reverse on MFC CArray
I have an array of points like this:
CArray<CPoint,CPoint> points;
And I need to change the order of the points. I tried this method:
std::reverse( &points[0], &points[0] + points.GetSize() );
And it works. Then I tried this other method:
std::reverse( &points[0], &points[points.GetUpperBound()] );
But that doesn't work: the last element is not properly ordered. Why?
source to share
This is because STL algorithms take ranges in the form [b, e) (ie e exclusive), whereas the function you used returns the position of the last actual last element .
It should also be noted that your second form is even more problematic when the array is empty. The function, according to the documentation, returns -1 in this case. BOOM!
source to share
First, while STL algorithms (including std::reverse()
) are designed to work with STL containers or STL-compatible containers (i.e. those that provide STL-compatible iterators), I'm not sure about combining them with MFC containers. <w> Of course, MFC containers were not designed with STL compatibility in mind.
I would suggest moving your code using MFC containers like CArray
to more modern containers like std::vector
.
However, in the second case:
std::reverse( &points[0], &points[points.GetUpperBound()] );
the second "iterator" argument you pass in std::reverse()
does not point to one-past the last valid element (as in the first case &points[0] + points.GetSize()
), but it actually points to the last valid element .
Actually CArray::GetUpperBound()
returns the last valid index (from MSDN documentation):
Since array indices are zero-based, this function returns 1 less
GetSize
.
You might be tempted to use something like &points[points.GetSize()]
or &points[points.GetUpperBound() + 1]
, but that might be unfortunate as it CArray
overloads operator[]
by implementing binding validation, at least in debug builds.
And with these aforementioned alternatives, you end up using an out of range index.
But let me repeat: consider porting your code from CArray
to std::vector
. You can still use MFC for the front-end GUI of your application; but for the "core" of your application for "business logic" it is better to use modern C ++ and STL containers.
source to share