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?

+3


source to share


3 answers


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!

+3


source


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.

+2


source







All Articles