简体   繁体   English

在MFC CArray上的std :: reverse

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM