为什么我不能在 lambda 函数中使用 unordered_map?那里传递的参数的数据类型是什么?
Why am I not able to use the unordered_map in lamda function ? What is the data type of arguements being passed there?
这是我的代码,它根据字符的频率对字符串进行排序。
string frequencySort(string s) {
unordered_map<char,int> umap;
for (int i=0 ; i<s.size() ; i++)
umap[s[i]]++ ;
sort (s.begin() , s.end() , [umap] (char a , char b) {
if (umap[a] == umap[b]) return a>b ;
return umap[a]>umap[b] ;
}) ;
return s ;
}
我收到这个错误:
Line 11: Char 21: error: no viable overloaded operator[] for type 'const unordered_map<char, int>'
if (umap[c] == umap[d]) return a>b ;
~~~~^~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:984:7: note: candidate function not viable: 'this' argument has type 'const unordered_map<char, int>', but method is not marked const
operator[](const key_type& __k)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:988:7: note: candidate function not viable: 'this' argument has type 'const unordered_map<char, int>', but method is not marked const
operator[](key_type&& __k)
^
lambda 的函数调用运算符 ()
默认设置为 const,因此您必须通过引用(&umap
或 &
)传递映射,或使用 mutable
关键字使运算符 ()
成为非常量并按值传递([umap]() mutable{}
或 [=]() mutable{}
):
通过引用传递地图:
#include <iostream>
#include <algorithm>
#include <unordered_map>
std::string frequencySort(std::string s) {
std::unordered_map<char,int> umap;
for (int i=0 ; i<s.size() ; i++)
umap[s[i]]++ ;
std::sort (s.begin() , s.end() , [&] (char a, char b) { // &umap
if (umap[a] == umap[b]) return a>b ;
return umap[a]>umap[b] ;
}) ;
return s;
}
int main()
{
std::string s = "lollypop";
std::cout << frequencySort(s); // prints lllppooy
return 0;
}
按值:
#include <iostream>
#include <algorithm>
#include <unordered_map>
std::string frequencySort(std::string s) {
std::unordered_map<char,int> umap;
for (int i=0 ; i<s.size() ; i++)
umap[s[i]]++ ;
std::sort (s.begin() , s.end() , [=] (char a, char b) mutable { // or [umap]
if (umap[a] == umap[b]) return a>b ;
return umap[a]>umap[b] ;
}) ;
return s;
}
int main()
{
std::string s = "lollypop";
std::cout << frequencySort(s); // prints lllppooy
return 0;
}
您的 lambda 正在按值 捕获 unordered_map
,因此创建了一个副本。由于 lambda 未标记为 mutable
,因此该副本将是 const
。并且 operator[]
没有为 const unordered_map
实现,因为如果找不到请求的键,它需要能够修改 unordered_map
以插入新元素。因此错误:
no viable overloaded operator[] for type 'const unordered_map<char, int>'
您需要通过引用 来捕获 unordered_map
:
sort (s.begin(), s.end(),
[&umap] (char a, char b) {
if (umap[a] == umap[b]) return a > b;
return umap[a] > umap[b];
}
);
但是,您随后会运行陷入一个新的问题。 unordered_map
的 value_type
不是 char
,而是 std::pair<const char, int>
,因此这是您需要用于 lambda 参数的类型,在这种情况下会有根本不需要捕获 unordered_map
:
sort (s.begin(), s.end(),
[] (const std::pair<const char, int> &a, const std::pair<const char, int> &b) {
if (a.second == b.second) return a.first > b.first;
return a.second > b.second;
}
);
但这也行不通。整个问题都没有实际意义,因为 you simply can't sort an unordered_map
to begin with。它根据键哈希对其元素进行排序,您无法使用 std::sort()
.
更改该顺序
请参阅 sort an unordered_map using sort() and Sorting std::unordered_map by key 了解替代方案。
这是我的代码,它根据字符的频率对字符串进行排序。
string frequencySort(string s) {
unordered_map<char,int> umap;
for (int i=0 ; i<s.size() ; i++)
umap[s[i]]++ ;
sort (s.begin() , s.end() , [umap] (char a , char b) {
if (umap[a] == umap[b]) return a>b ;
return umap[a]>umap[b] ;
}) ;
return s ;
}
我收到这个错误:
Line 11: Char 21: error: no viable overloaded operator[] for type 'const unordered_map<char, int>'
if (umap[c] == umap[d]) return a>b ;
~~~~^~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:984:7: note: candidate function not viable: 'this' argument has type 'const unordered_map<char, int>', but method is not marked const
operator[](const key_type& __k)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:988:7: note: candidate function not viable: 'this' argument has type 'const unordered_map<char, int>', but method is not marked const
operator[](key_type&& __k)
^
lambda 的函数调用运算符 ()
默认设置为 const,因此您必须通过引用(&umap
或 &
)传递映射,或使用 mutable
关键字使运算符 ()
成为非常量并按值传递([umap]() mutable{}
或 [=]() mutable{}
):
通过引用传递地图:
#include <iostream>
#include <algorithm>
#include <unordered_map>
std::string frequencySort(std::string s) {
std::unordered_map<char,int> umap;
for (int i=0 ; i<s.size() ; i++)
umap[s[i]]++ ;
std::sort (s.begin() , s.end() , [&] (char a, char b) { // &umap
if (umap[a] == umap[b]) return a>b ;
return umap[a]>umap[b] ;
}) ;
return s;
}
int main()
{
std::string s = "lollypop";
std::cout << frequencySort(s); // prints lllppooy
return 0;
}
按值:
#include <iostream>
#include <algorithm>
#include <unordered_map>
std::string frequencySort(std::string s) {
std::unordered_map<char,int> umap;
for (int i=0 ; i<s.size() ; i++)
umap[s[i]]++ ;
std::sort (s.begin() , s.end() , [=] (char a, char b) mutable { // or [umap]
if (umap[a] == umap[b]) return a>b ;
return umap[a]>umap[b] ;
}) ;
return s;
}
int main()
{
std::string s = "lollypop";
std::cout << frequencySort(s); // prints lllppooy
return 0;
}
您的 lambda 正在按值 捕获 unordered_map
,因此创建了一个副本。由于 lambda 未标记为 mutable
,因此该副本将是 const
。并且 operator[]
没有为 const unordered_map
实现,因为如果找不到请求的键,它需要能够修改 unordered_map
以插入新元素。因此错误:
no viable overloaded operator[] for type 'const unordered_map<char, int>'
您需要通过引用 来捕获 unordered_map
:
sort (s.begin(), s.end(),
[&umap] (char a, char b) {
if (umap[a] == umap[b]) return a > b;
return umap[a] > umap[b];
}
);
但是,您随后会运行陷入一个新的问题。 unordered_map
的 value_type
不是 char
,而是 std::pair<const char, int>
,因此这是您需要用于 lambda 参数的类型,在这种情况下会有根本不需要捕获 unordered_map
:
sort (s.begin(), s.end(),
[] (const std::pair<const char, int> &a, const std::pair<const char, int> &b) {
if (a.second == b.second) return a.first > b.first;
return a.second > b.second;
}
);
但这也行不通。整个问题都没有实际意义,因为 you simply can't sort an unordered_map
to begin with。它根据键哈希对其元素进行排序,您无法使用 std::sort()
.
请参阅 sort an unordered_map using sort() and Sorting std::unordered_map by key 了解替代方案。