...
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];
};
...
This give me no viable overloaded operator[] for type 'const unordered_map<std::__cxx11::string, int>' (aka 'const unordered_map<basic_string<char>, int>')
But if I don't use [] operator but rather use .at() for access. The code compiles.
I don't know why. I check out [] operator and .at() : both have the same method signature.
Variables captured in a lambda are const
by default, unless you mark the lambda as mutable
. unordered_map
does not have an operator[]
that can be called on a const unordered_map
object, since it inserts (ie modifies) a new element if the requested key is not found.
Also, you are capturing map
by value, you should capture it by reference instead (unless you are expecting cmp
to outlive map
).
Try this:
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 < ?
};