[英]std::reverse on MFC CArray
I have an array of points like this: 我有一系列像这样的点:
CArray<CPoint,CPoint> points;
And I need to reverse the order of the points. 我需要扭转积分的顺序。 I've tried this method: 我试过这个方法:
std::reverse( &points[0], &points[0] + points.GetSize() );
And it works. 它有效。 Then I've tried this other method: 然后我尝试了另一种方法:
std::reverse( &points[0], &points[points.GetUpperBound()] );
But it doesn't work: the last item is not ordered correctly. 但它不起作用:最后一项没有正确排序。 Why? 为什么?
That is because STL algorithms take ranges in the form [b, e) (that is, e exclusive), whereas the function you used returns the position of the last actual last element . 这是因为STL算法采用[b,e]形式的范围(即, e独占),而您使用的函数返回最后一个实际最后一个元素的位置 。
It should be further noted that your second form is even more problematic in the case where the array is empty. 应该进一步注意的是,在阵列为空的情况下,您的第二种形式甚至更成问题。 The function, according to the documentation, returns -1 in this case. 根据文档,该函数在这种情况下返回-1。 BOOM! 繁荣!
First, while STL's algorithms (including std::reverse()
) are designed to work fine with STL containers or STL-compatible containers (ie those providing STL-compatible iterators), I'm not sure about combining them with MFC containers . 首先,虽然STL的算法(包括std::reverse()
)被设计为可以与STL容器或STL兼容的容器(即那些提供STL兼容的迭代器)一起使用,但我不确定是否将它们与MFC容器结合使用。
Certainly, MFC containers were not designed with STL algorithm compatibility in mind. 当然,MFC容器的设计并没有考虑到STL算法的兼容性。
I'd suggest to move your code from using MFC containers like CArray
to more modern containers like std::vector
. 我建议将代码从使用像CArray
这样的MFC容器转移到更现代的容器,比如std::vector
。
That said, in the second case here: 那就是说,在这里的第二种情况:
std::reverse( &points[0], &points[points.GetUpperBound()] );
the second "iterator" argument that you pass to std::reverse()
is not pointing to one-past the last valid item (like in the first case of &points[0] + points.GetSize()
), but it's actually pointing to the last valid item . 您传递给第二个“迭代”的说法std::reverse()
不 (在第一种情况下像指向一个过去的最后一个有效的项目&points[0] + points.GetSize()
但它的实际指向到最后一个有效项目 。
In fact, CArray::GetUpperBound()
returns the last valid index (from MSDN documentation): 实际上, CArray::GetUpperBound()
返回最后一个有效索引(来自MSDN文档):
Because array indexes are zero-based, this function returns a value 1 less than
GetSize
. 由于数组索引从零开始,因此此函数返回的值比GetSize
小1。
You may be tempted to use something like &points[points.GetSize()]
or &points[points.GetUpperBound() + 1]
, but those would fail, since CArray
overloads operator[]
, implementing bound checking at least in debug builds. 您可能想要使用类似&points[points.GetSize()]
或&points[points.GetUpperBound() + 1]
,但这些会失败,因为CArray
重载operator[]
,至少在调试版本中实现绑定检查。
And with these aforementioned alternatives, you end up using an index out of the valid range. 使用上述替代方案,您最终会使用有效范围之外的索引。
But, let me repeat: consider moving your code from CArray
to std::vector
. 但是,让我重复一遍:考虑将代码从CArray
移动到std::vector
。 You can still use MFC for the front-end GUI of your application; 您仍然可以将MFC用于应用程序的前端GUI; but for the "core" of your application, for the "business logic", using modern C++ and STL containers is a better option. 但对于应用程序的“核心”,对于“业务逻辑”,使用现代C ++和STL容器是更好的选择。
文档说GetUpperBound()
返回最后一个元素的索引,因此&points[points.GetUpperBound()]
表示最后一个元素的迭代器,而STL算法需要半开范围,如[begin, end)
,即end
必须直接指向最后一个元素 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.