std::reverse on MFC CArray

std::reverse on MFC CArray

本文关键字:CArray MFC reverse std on      更新时间:2023-10-16

我有一个点数组,如下所示:

CArray<CPoint,CPoint> points;

我需要颠倒要点的顺序。我试过这种方法:

std::reverse( &points[0], &points[0] + points.GetSize() );

它是有效的。然后我尝试了另一种方法:

std::reverse( &points[0], &points[points.GetUpperBound()] );

但它不起作用:最后一项没有正确排序。为什么?

这是因为STL算法采用[b,e((即e互斥(形式的范围,而您使用的函数返回最后一个实际元素的位置。


需要进一步注意的是,在数组为空的情况下,第二种形式的问题会更大。根据文档,函数在这种情况下返回-1。轰!

文档说GetUpperBound()返回最后一个元素的索引,所以&points[points.GetUpperBound()]表示最后一个元件的迭代器,而STL算法需要像[begin, end)这样的半开范围,也就是说,end必须直接指向最后一个元素之后的

首先,虽然STL的算法(包括std::reverse()(被设计为与STL容器或STL兼容容器(即那些提供STL兼容迭代器的容器(配合良好,但我不确定是否将它们与MFC容器组合
当然,MFC容器在设计时考虑到了STL算法的兼容性,而不是。

我建议您将代码从使用像CArray这样的MFC容器转移到像std::vector这样的更现代的容器。

也就是说,在这里的第二种情况下:

std::reverse( &points[0], &points[points.GetUpperBound()] );

传递给std::reverse()的第二个"迭代器">参数是,而不是指向最后一个有效项的前一个(就像&points[0] + points.GetSize()的第一种情况一样(,但它实际上指向最后有效项。

事实上,CArray::GetUpperBound()返回最后一个有效索引(来自MSDN文档(:

因为数组索引是从零开始的,所以此函数返回值1小于CCD_ 11。

您可能会想使用类似&points[points.GetSize()]&points[points.GetUpperBound() + 1]的东西,但这些都会失败,因为CArray重载了operator[],至少在调试构建中实现了绑定检查
使用上述替代方案,您最终会使用超出有效范围的索引。

但是,让我重复一遍:考虑将代码从CArray移动到std::vector。您仍然可以使用MFC作为应用程序的前端GUI;但对于应用程序的"核心",对于"业务逻辑",使用现代C++和STL容器是一个更好的选择。

您可以使用堆栈反转数组链接:

#include <stack>
using namespace std;
void ReverseArray(CArray<CPoint,CPoint> points, int n)
{
    // create an empty stack of integers
    stack<CPoint,CPoint> stack;
    // push each array element into a stack
    for (int i = 0; i < n; i++) {
        stack.push(points[i]);
    }
    // start from index 0
    int index = 0;
    // pop values from the stack until it becomes empty
    while (!stack.empty())
    {
        // assign each popped item back to the original array
        points[index++] = stack.top();
        stack.pop();
    }
}

有关详细信息,请参阅https://www.techiedelight.com/reverse-an-array-cpp/