我目前正在开发一个程序,必须为该程序创建一个映射以使用特定键存储数据。尽管可以对该键进行严格的弱排序,但是相对于键的含义,该排序没有意义。因此,我决定给我的地图一个比较器lambda,而不是覆盖我的键类型上的operator <。但是,执行此操作时,会出现大量编译错误,这些错误似乎可以归结为无法将lambda转换为编译器所需类型的想法。为什么会这样?
最少完整的可验证示例:
#include <iostream>
#include <map>
struct CustomClass{
unsigned a;
};
int main(){
std::map<CustomClass, int> bad_map([](const CustomClass &a, const CustomClass &b){ return a.a < b.a; });
}
Linux上出现Clang 6.0.1错误:
$ clang++ bug.cpp -o bug
bug11.cpp:9:29: error: no matching constructor for initialization of 'std::map<CustomClass, int>'
std::map<CustomClass, int> bad_map([](const CustomClass &a, const CustomClass &b){ return a.a < b.a; });
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:192:7: note: candidate constructor not viable: no known conversion from '(lambda at bug11.cpp:9:37)' to
'const std::less<CustomClass>' for 1st argument
map(const _Compare& __comp,
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:205:7: note: candidate constructor not viable: no known conversion from '(lambda at bug11.cpp:9:37)' to 'const
std::map<CustomClass, int, std::less<CustomClass>, std::allocator<std::pair<const CustomClass, int> > >' for 1st argument
map(const map&) = default;
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:213:7: note: candidate constructor not viable: no known conversion from '(lambda at bug11.cpp:9:37)' to
'std::map<CustomClass, int, std::less<CustomClass>, std::allocator<std::pair<const CustomClass, int> > >' for 1st argument
map(map&&) = default;
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:226:7: note: candidate constructor not viable: no known conversion from '(lambda at bug11.cpp:9:37)' to
'initializer_list<std::map<CustomClass, int, std::less<CustomClass>, std::allocator<std::pair<const CustomClass, int> > >::value_type>' (aka 'initializer_list<pair<const CustomClass, int> >') for
1st argument
map(initializer_list<value_type> __l,
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:234:7: note: candidate constructor not viable: no known conversion from '(lambda at bug11.cpp:9:37)' to 'const
std::map<CustomClass, int, std::less<CustomClass>, std::allocator<std::pair<const CustomClass, int> > >::allocator_type' (aka 'const std::allocator<std::pair<const CustomClass, int> >') for 1st
argument
map(const allocator_type& __a)
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:254:2: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
map(_InputIterator __first, _InputIterator __last,
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:271:2: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
map(_InputIterator __first, _InputIterator __last)
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:288:2: note: candidate constructor template not viable: requires at least 3 arguments, but 1 was provided
map(_InputIterator __first, _InputIterator __last,
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:183:7: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
map() = default;
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:238:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
map(const map& __m, const allocator_type& __a)
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:242:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
map(map&& __m, const allocator_type& __a)
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.2.1/../../../../include/c++/8.2.1/bits/stl_map.h:248:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
map(initializer_list<value_type> __l, const allocator_type& __a)
^
1 error generated.