如何使用std::greater对C++ map键进行排序?

7
我正在用C++创建一个std::map<int, int>,我希望它的键按照从大到小的顺序排序而不是默认的排序顺序。我的研究引导我找到了std::greater,看起来很有前途,但是当我尝试使用它时,我得到了一个编译错误:

invalid type argument of unary ‘*’ (have ‘int’)

我的map声明如下:

std::map<int, int, std::greater<int> > numMap;

错误来自于这个函数:

void Row::addNumber(int num, int pos) {
    numMap.insert(num, pos);
}

类似问题的答案,如此链接所提到的,在声明中需要加上括号,即 std::greater() - 但是当我加入这些内容后,会出现多个有关函数返回函数的错误。

当您倒着阅读地图时,您的问题难道不会解决吗?仅供参考。 - fonZ
1
你是说当你使用std::map的默认比较器时,就不会出现同样的错误吗?因为在这种情况下,这应该没有任何影响。 - Benjamin Lindley
2个回答

7
问题 - 使用无效参数调用std :: map :: insert成员函数:提供了两个整数值; 但是必须是std :: pair 。请参阅参考文献:std :: map :: insert
首选选项
为了方便起见(只是不重复地重复地图类型参数),为地图创建typedef:
typedef std::map<int, int> IntMap;
std::map有类型定义std::pair(对表示)- std::map::value_type。 例如,如果有一个std::map<int, int>,那么std::map::value_type将是std::pair<int, int>
使用std::map::value_type构造函数(在这种情况下为IntMap::value_type):
class Row {
public:
    void Row::addNumber(int num, int pos)
    {
        m_numMap.insert(IntMap::value_type(num, pos));
    }

private:
    typedef std::map<int, int> IntMap;
    IntMap m_numMap;
};

替代方案:

  1. Use std::make_pair() function:

    #include <utility>
    
    ...
    
    void Row::addNumber(int num, int pos)
    {
        numMap.insert(std::make_pair(num, pos));
    }
    
  2. Directly use std::pair constructor:

    void Row::addNumber(int num, int pos)
    {
        numMap.insert(std::pair<int, int>(num, pos));
    }
    

非常同意。插入函数并不像你想象的那样工作。:( - Xymostech
啊,谢谢。我一直以为C++的map插入函数和Java的map.put函数是一样的,显然我应该更多地进行研究 :-( - frostmatthew
1
顺便提一下,如果你在Java中使用过HashMap类,那么你可能想要使用自C++11以来可用的std::unordered_map类——哈希映射容器。 - Sergey Vyacheslavovich Brunov
谢谢,以后有用。不过在这个特定情况下,我确实需要地图有序。 - frostmatthew

5
有点比Sergey的答案更严谨(当然,他的方法也可行),建议使用以下方式:
typedef std::map<int, int, std::greater<int> > MyMap;
MyMap numMap;

void Row::addNumber(int num, int pos)
{
    numMap.insert(MyMap::value_type(num, pos));
}

这样做的好处是,如果你更改了地图的类型,你需要修改的代码就会更少。而且虽然不太可能发生,但如果在将来的stl版本中实现了std::mapvalue_type std :: pair 更改为其他东西,你也可以应对这种变化。


没错,你说得对:std::map::value_type非常方便(不需要重复std::map类型的参数)。 - Sergey Vyacheslavovich Brunov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接