...
unordered_map<string ,int> map;
for (const auto& str : words) {
map[str]++;
}
auto cmp = [map](string s1, string s2){
if (map[s1] == map[s2])
return s1 < s2;
return map[s1] > map[s2];
};
...
这给我no viable overloaded operator[] for type 'const unordered_map<std::__cxx11::string, int>' (aka 'const unordered_map<basic_string<char>, int>')
但如果我不使用[]运算符,而是使用.at((进行访问。代码编译。
我不知道为什么。我检查了[]运算符和.at((:它们都有相同的方法签名。
我签出了[]运算符和.at((:两者都有相同的方法签名。
否。不能在const
map
上调用std::map::operator[]
。它可能会修改map
(如果指定的密钥不存在(。(BTWstd::map::at
不会修改map
,如果指定的密钥不存在,它会抛出std::out_of_range
。(
您可以用mutable
标记lambda;否则lambda的operator()
是常量限定的,并且通过复制捕获的对象也是const
,则不能对其调用operator[]
。
mutable:允许body修改通过复制捕获的对象,并调用它们的非常量成员函数
除非在lambda表达式中使用了关键字mutable,否则函数调用运算符是const限定的通过复制捕获的是不可从此CCD_ 13内部修改的。
例如
auto cmp = [map](string s1, string s2) mutable {
if (map[s1] == map[s2])
return s1 < s2;
return map[s1] > map[s2];
};
PS:不使用名称map
作为变量是个好主意。
const
,除非将lambda标记为mutable
。unordered_map
没有可以在const unordered_map
对象上调用的operator[]
,因为如果找不到请求的密钥,它会插入(即修改(一个新元素。
此外,如果要通过值捕获map
,则应通过引用来捕获它(除非您希望cmp
的寿命比map
长(。
试试这个:
unordered_map<string, int> word_counts;
for (const auto& str : words) {
word_counts[str]++;
}
auto cmp = [&word_counts](const string &word1, const string &word2){
auto iter = word_counts.find(word1);
int count1 = (iter != word_counts.end()) ? iter->second : 0;
iter = word_counts.find(word2);
int count2 = (iter != word_counts.end()) ? iter->second : 0;
/* or, throw an exception if word1 or word2 are not found...
int count1 = word_counts.at(word1);
int count2 = word_counts.at(word2);
*/
if (count1 == count2)
return word1 < word2;
return count1 > count2; // <-- why > and not < ?
};