如何为地图创建自己的比较器?

问题描述 投票:64回答:3
typedef map<string, string> myMap;

当向myMap插入一个新对时,它将使用密钥string来比较它自己的字符串比较器。是否可以覆盖该比较器?例如,我想比较密钥string的长度,而不是字母表。或者还有其他方法可以对地图进行排序吗?

c++ stl stdmap
3个回答
107
投票

std::map最多需要四个模板类型参数,第三个是比较器。例如。:

struct cmpByStringLength {
    bool operator()(const std::string& a, const std::string& b) const {
        return a.length() < b.length();
    }
};

// ...
std::map<std::string, std::string, cmpByStringLength> myMap;

或者你也可以将比较器传递给maps constructor

但请注意,按长度比较时,地图中每个长度只能有一个字符串作为键。


11
投票

是的,map上的第3个模板参数指定比较器,它是二进制谓词。例:

struct ByLength : public std::binary_function<string, string, bool>
{
    bool operator()(const string& lhs, const string& rhs) const
    {
        return lhs.length() < rhs.length();
    }
};

int main()
{
    typedef map<string, string, ByLength> lenmap;
    lenmap mymap;

    mymap["one"] = "one";
    mymap["a"] = "a";
    mymap["fewbahr"] = "foobar";

    for( lenmap::const_iterator it = mymap.begin(), end = mymap.end(); it != end; ++it )
        cout << it->first << "\n";
}

8
投票

C++11开始,你也可以使用lambda expression而不是定义比较器结构:

auto comp = [](const string& a, const string& b) { return a.length() < b.length(); };
map<string, string, decltype(comp)> my_map(comp);

my_map["1"]      = "a";
my_map["three"]  = "b";
my_map["two"]    = "c";
my_map["fouuur"] = "d";

for(auto const &kv : my_map)
    cout << kv.first << endl;

输出:

1 二 三 四

我想重复Georg的答案的最后一点:当按长度比较时,你只能在地图中将每个长度的一个字符串作为键。

Code on Ideone

© www.soinside.com 2019 - 2024. All rights reserved.