尝试对 std::map<int, class> 进行排序时出错

Posted

技术标签:

【中文标题】尝试对 std::map<int, class> 进行排序时出错【英文标题】:Error while trying to sort std::map<int, class> 【发布时间】:2020-05-12 08:32:20 【问题描述】:

我正在尝试订购一个 std::map,这个映射有一个 int 作为键,一个类作为第二个元素。 这是代码:

#include <vector>
#include <algorithm>
#include <map>


class Position 


public:
    bool operator < (const Position & pos) 
        return x < pos.x;
    
    bool operator > (const Position & pos) 
        return x > pos.x;
    
    int x;
    int y;
;

class Element 
public:
    bool operator < (const Element & pos) 
        return position.x < pos.position.x;
    
    bool operator > (const Element & pos) 
        return position.x > pos.position.x;
    
    int order;
    Position position;
;

bool IsGreater(const std::pair<int, Element>& e1,const std::pair<int, Element>& e2) 
    return e1.second.position.x > e2.second.position.x;


using namespace std;

int main()

    std::map<int,Element> elements;
    Element e1;
    Element e2;
    Element e3;
    e1.position.x = 2;
    e2.position.x = 1;
    e3.position.x = 0;
    elements.insert(std::pair<int, Element>(2, e1));
    elements.insert(std::pair<int, Element>(1, e2));
    elements.insert(std::pair<int, Element>(0, e3));

    std::sort(elements.begin(), elements.end(), IsGreater);

    for (unsigned int x = 0; x < elements.size(); x++) 
        printf("Element %d order: %d\n", x, elements.at(x).order);
    

    return 0;


基本上我有 2 个类,它们是 Position(包含 x 和 y 坐标)和 Element(包含索引和位置)。 我需要按位置中的 x 坐标对这张地图进行排序,但是当我尝试编译代码时,我遇到了这 3 个问题:

Error   C2676   binary '-': 'const std::_Tree_unchecked_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const int,Element>>>>' does not define this operator or a conversion to a type acceptable to the predefined operator  TestSort    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\algorithm   3506    
Error   C2672   '_Sort_unchecked': no matching overloaded function found    TestSort    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\algorithm   3506    
Error   C2780   'void std::_Sort_unchecked(_RanIt,_RanIt,iterator_traits<_Iter>::difference_type,_Pr)': expects 4 arguments - 3 provided    TestSort    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\algorithm   3506    

最初我尝试使用elements.begin() 和elements.end() 调用std::sort,没有用,然后我尝试在元素类中包含运算符oveload ""。 ..没有运气,然后我尝试添加运算符重载“”……但再次没有运气!我尝试使用 lambda 表达式作为 sort 方法的第三个参数,什么都没有……最后我尝试为返回 bool 的排序创建一个单独的函数……但没有任何效果。 我根本无法理解问题所在,也无法找出问题所在。 我的问题是: 1)这个错误告诉我什么? 2)我该如何解决? 提前感谢您的帮助!

【问题讨论】:

不存在未排序的地图之类的东西,因此您一开始就不能也不需要对其进行排序。 (并且排序是由键完成的,与它们的值无关) 好的,所以基本上我无法对 std::map 进行排序? 原则上可以,但不会有任何明显的效果。 std::map 已按设计排序:"std::map is a sorted associative container that contains key-value pairs with unique keys"。 但是当我尝试使用 来完成它时,它可以完成并且我看到它实际上是重新排序的,这不应该是类或实现中的问题吗? 【参考方案1】:

您不能在 std::map 上使用 std::sort,因为

std::sort required random access iterators 但std::map&lt;Key, T&gt;::iterator 只是bidirectional iterator。 std::map&lt;Key, T&gt;::value_typestd::pair&lt;const Key, T&gt;,因此您不能像 std::sort 中所要求的那样更改值的 Key。原因正是因为std::map 是按设计排序的,因此您不应手动尝试对值进行“重新排序”;这样做基本上会破坏容器,导致未定义的行为。

如果您想按其他条件对 map 中的值进行排序,您应该重新评估 std::map 是否真的是您想要的;也许std::vector&lt;std::pair&lt;Key, T&gt;&gt; 会更好,或者您必须将值复制或引用到其他容器(即std::vector)并对其进行排序。

【讨论】:

让我害怕“复制”这个词的东西是因为我想要一个低内存占用,因为里面有很多很多元素,我可以,也许,使用地图来存储元素和带有指向元素指针的向量?我的意思是 std::map std::vector<:pair element>> 您可以根据需要执行此操作(尽管您不会节省大量内存)。为什么你认为你需要std::map?如果你真的那么在意内存,那么std::map 几乎肯定不是正确的选择——它很少是这样。 我在使用它时假设我会以不同的方式使用密钥,例如 guid 或字符串

以上是关于尝试对 std::map<int, class> 进行排序时出错的主要内容,如果未能解决你的问题,请参考以下文章

为啥我可以在 std::map<std::string, int> 中使用 const char* 作为键

使用 gdb 检查标准容器 (std::map) 内容

具有结构错误值的 std::map

std::unordered_map<int32_t, int32_t> 在堆上声明

将空向量放入 std::map()

std::map 作为类成员