#include <set>
#include <string>
#include <unordered_map>
#include <vector>
int main()
{
std::vector<std::string> wordsContainer={"aba", "baba","ris", "u"};
auto cmp=[&](int i, int j){
if (wordsContainer[i].size() != wordsContainer[j].size())
return wordsContainer[i].size() < wordsContainer[j].size();
return i < j;
};
std::unordered_map<int,std::set<int,decltype(cmp)>>mp;
mp[0].insert(2); // <-- this line is the issue
}
我正在尝试在 C++20 中做类似的事情。我希望我的容器根据其他容器进行排序。但是编译器抱怨 cmp 的类型,从 [&] 中删除 & 可以,但我无法访问变量wordsContainer。
In file included from /opt/rh/devtoolset-10/root/usr/include/c++/10/map:60,
from /opt/rh/devtoolset-10/root/usr/include/c++/10/x86_64-redhat-linux/bits/stdc++.h:81,
from main.cpp:1:
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree_key_compare<_Key_compare>::_Rb_tree_key_compare() [with _Key_compare = main()::<lambda(int, int)>]’:
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h:688:22: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Rb_tree_impl<_Key_compare, <anonymous> >::_Rb_tree_impl() [with _Key_compare = main()::<lambda(int, int)>; bool <anonymous> = false; _Key = int; _Val = int; _KeyOfValue = std::_Identity<int>; _Compare = main()::<lambda(int, int)>; _Alloc = std::allocator<int>]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h:935:7: required from ‘constexpr std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {int&&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = std::__debug::set<int, main()::<lambda(int, int)> >]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/tuple:1678:63: required from ‘constexpr std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {int&&}; _Args2 = {}; _T1 = const int; _T2 = std::__debug::set<int, main()::<lambda(int, int)> >]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_construct.h:97:14: required from ‘constexpr decltype (::new(void*(0)) _Tp) std::construct_at(_Tp*, _Args&& ...) [with _Tp = std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; decltype (::new(void*(0)) _Tp) = std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >*]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/alloc_traits.h:514:4: required from ‘static constexpr void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > > >]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h:618:32: required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >; _KeyOfValue = std::_Select1st<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >*]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h:635:21: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >; _KeyOfValue = std::_Select1st<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >*]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h:2461:33: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >; _KeyOfValue = std::_Select1st<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<int, std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >, std::_Select1st<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >, std::less<int>, std::allocator<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > > >::iterator; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree<int, std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > >, std::_Select1st<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >, std::less<int>, std::allocator<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > > >::const_iterator]’
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_map.h:520:37: required from ‘std::__cxx1998::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::__cxx1998::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::__cxx1998::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = int; _Tp = std::__debug::set<int, main()::<lambda(int, int)> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::__debug::set<int, main()::<lambda(int, int)> > > >; std::__cxx1998::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::__debug::set<int, main()::<lambda(int, int)> >; std::__cxx1998::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’
main.cpp:339:9: required from here
/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_tree.h:149:24: error: use of deleted function ‘main()::<lambda(int, int)>::<lambda>()’
149 | : _M_key_compare()
| ^
main.cpp:333:16: note: a lambda closure type has a deleted default constructor
333 | auto cmp=[&](int i, int j){
| ^
编译器选项:
-std=c++20 -O2 -Wall -Wextra -Wshadow -Wconversion -Wfloat-equal -Wduplicated-cond -W逻辑操作 -Wall -Wextra -O2 -W逻辑操作 -Wshift-overflow -Wduplicated-cond -Wcast -qual -Wcast-align -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDATIC -D_FORTIFY_SOURCE=2 -fno-sanitize-recover -fstack-protector
我也尝试过
std::unordered_map<int,std::set<int,decltype(cmp)>>mp;
但它给出了:
main.cpp:338:21: error: type/value mismatch at argument 2 in template parameter list for ‘template<class _Key, class _Cmp, class _Allocator> class std::__debug::set’
338 | map<int,set<int,cmp>>mp;
| ^~~
main.cpp:338:21: note: expected a type, got ‘cmp’
main.cpp:338:24: error: template argument 2 is invalid
338 | map<int,set<int,cmp>>mp;
| ^~
main.cpp:338:24: error: template argument 4 is invalid
main.cpp:339:7: error: invalid types ‘int[int]’ for array subscript
339 | mp[0].insert(2);
有办法实现这一点吗?我调查了this,但没有帮助。
您不能使用地图的operator[],因为它需要默认构建您的集合。并且你不能默认构造
std::set<int, decltype(cmp)> mySet;
,因为你不能默认构造捕获 lambda 的实例。
您可以使用
insert: 代替
operator[]
mp.insert(std::make_pair(0, std::set<int, decltype(cmp)>{cmp}));
mp.at(0).insert(2);
但请注意,您的比较器的逻辑可能会被破坏,例如如果您插入的元素大于/等于您的 wordsContainer
的大小,则会导致
未定义的行为。