在MFC CArray上的std :: reverse

时间:2015-05-25 14:44:26

标签: c++ stl mfc

我有一系列像这样的点:

CArray<CPoint,CPoint> points;

我需要扭转积分的顺序。我尝试过这种方法:

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

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

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

但它不起作用:最后一项未正确订购。为什么呢?

4 个答案:

答案 0 :(得分:3)

这是因为STL算法采用 [b,e] 形式的范围(即 e 独占),而the function you used returns the position of the last actual last element

应该进一步注意的是,在阵列为空的情况下,您的第二种形式甚至更成问题。根据文档,该函数在这种情况下返回-1。 BOOM!

答案 1 :(得分:2)

首先,虽然STL的算法(包括std::reverse())被设计为可以与STL容器或STL兼容的容器(即那些提供STL兼容的迭代器)一起使用,但我不确定是否将它们与 MFC容器 当然,MFC容器设计时考虑到了STL算法的兼容性。

我建议将代码从使用CArray等MFC容器转移到更现代的容器std::vector

那就是说,在第二种情况下:

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

您传递给std::reverse()的第二个“iterator”参数是而不是指向过去最后一个有效项目(与&points[0] + points.GetSize()的第一种情况一样),但它实际上指的是最后一个有效项

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

  

因为数组索引从零开始,所以此函数返回值1   小于GetSize

您可能会尝试使用&points[points.GetSize()]&points[points.GetUpperBound() + 1]之类的内容,但这些内容会失败,因为CArray重载operator[],至少在调试版本中实现绑定检查。
使用上述替代方案,您最终会使用有效范围之外的索引。

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

答案 2 :(得分:1)

documentation表示GetUpperBound()返回最后一个元素的索引,因此&points[points.GetUpperBound()]表示最后一个元素的迭代器,而STL算法需要半开范围,如{{1} },即[begin, end)必须在最后一个元素之后直接指向

答案 3 :(得分:0)

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

#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/