地图上的std :: set_difference和向量抛出转换错误

问题描述

以下代码应计算地图和矢量的差

std::map<int,int> cursorMap;
QVector<User> userList;
...
std::vector<int> offlineUserIds{};
std::vector<int>::iterator it;
it = std::set_difference(cursorMap.begin(),cursorMap.end(),userList.begin(),userList.end(),offlineUserIds.begin(),[](const std::pair<int,int> &e,const User &u){ return u.getId() == e.first; });

调用set_difference之前,userList被转换为std::vector并进行排序。问题是它给了我以下错误

error: cannot convert 'std::pair<const int,int>' to 'int' in assignment
...
error: no match for call to '(TextEditor::updateCursorMap(QVector<User>)::<lambda(const std::pair<int,int>&,const User&)>) (User&,std::pair<const int,int>&)'
         { return bool(_M_comp(*__it1,*__it2)); }
...
note: candidate: 'TextEditor::updateCursorMap(QVector<User>)::<lambda(const std::pair<int,const User&)>'
...
     it = std::set_difference(cursorMap.begin(),const User &u){ return u.getId() == e.first; });
...
note:   no kNown conversion for argument 1 from 'User' to 'const std::pair<int,int>&'

编辑:

我尝试了以下代码

std::map<int,int> cursorMap;
QVector<User> userList;
...
std::vector<std::pair<int,int>> offlineUserIds{};
std::vector<std::pair<int,int>>::iterator it;
it = std::set_difference(cursorMap.begin(),const User &u){ return e.first < u.getId(); });

但是现在它给了我

note: candidate: 'TextEditor::updateCursorMap(QVector<User>)::<lambda(const std::pair<int,const User&)>'
     it = std::set_difference(cursorMap.begin(),const User &u){ return e.first < u.getId(); });
...
note:   no kNown conversion for argument 1 from 'User' to 'const std::pair<int,int>&'

EDIT2:

这是一个最小的可重现示例:

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

class User {
    int id;
public:
    int getId() const { return id; }
};


int main() {
    std::vector<User> newUserList{};
    std::map<int,int> cursorMap{};
    std::vector<User> userList = std::vector(newUserList.begin(),newUserList.end());
    std::sort(userList.begin(),[](const User &u1,const User &u2) { return u1.getId() < u2.getId(); });

    std::vector<std::pair<int,int>> offlineUserIds{};
    std::vector<std::pair<int,int>>::iterator it;
    it = std::set_difference(cursorMap.begin(),[](std::pair<int,int> e,User u){ return e.first < u.getId(); });

    return 0;
}

构建输出

In file included from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algobase.h:71,from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/char_traits.h:39,from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:40,from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from D:\asant\workspace\CLionProjects\untitled\main.cpp:1:
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/predefined_ops.h: In instantiation of 'constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1,_Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<User*,std::vector<User> >; _Iterator2 = std::_Rb_tree_iterator<std::pair<const int,int> >; _Compare = main()::<lambda(std::pair<int,int>,User)>]':
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:5343:17:   required from '_OutputIterator std::__set_difference(_InputIterator1,_InputIterator1,_InputIterator2,_OutputIterator,_Compare) [with _InputIterator1 = std::_Rb_tree_iterator<std::pair<const int,int> >; _InputIterator2 = __gnu_cxx::__normal_iterator<User*,std::vector<User> >; _OutputIterator = __gnu_cxx::__normal_iterator<std::pair<int,int>*,std::vector<std::pair<int,int> > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(std::pair<int,User)> >]'
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:5447:46:   required from '_OIter std::set_difference(_IIter1,_IIter1,_IIter2,_OIter,_Compare) [with _IIter1 = std::_Rb_tree_iterator<std::pair<const int,int> >; _IIter2 = __gnu_cxx::__normal_iterator<User*,std::vector<User> >; _OIter = __gnu_cxx::__normal_iterator<std::pair<int,int> > >; _Compare = main()::<lambda(std::pair<int,User)>]'
D:\asant\workspace\CLionProjects\untitled\main.cpp:21:188:   required from here
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/predefined_ops.h:143:18: error: no match for call to '(main()::<lambda(std::pair<int,User)>) (User&,*__it2)); }
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/predefined_ops.h:143:18: note: candidate: 'bool (*)(std::pair<int,User)' <conversion>
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/predefined_ops.h:143:18: note:   candidate expects 3 arguments,3 provided
D:\asant\workspace\CLionProjects\untitled\main.cpp:21:156: note: candidate: 'main()::<lambda(std::pair<int,User)>'
     it = std::set_difference(cursorMap.begin(),User u){ return e.first < u.getId(); });
                                                                                                                                                            ^
D:\asant\workspace\CLionProjects\untitled\main.cpp:21:156: note:   no kNown conversion for argument 1 from 'User' to 'std::pair<int,int>'
mingw32-make.exe[3]: *** [CMakeFiles\untitled.dir\build.make:82: CMakeFiles/untitled.dir/main.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:95: CMakeFiles/untitled.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:102: CMakeFiles/untitled.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:137: untitled] Error 2

解决方法

由于我不知道的原因:

Type1和Type2类型必须使得InputIt1类型的对象 和InputIt2可以取消引用,然后然后隐式转换为两者 Type1和Type2

请参见cppreference。参数-> comp下的最后一句话。由我突出显示。

,

模板类std::map的值类型定义如下

typedef pair<const Key,T> value_type;

但是类std::vector<int>的值类型为int

不能将类型为std::pair的对象分配给类型为int的对象。

所以编译器会发出错误消息。

此外,可以使用传递参数的任何顺序来调用比较函数。因此,再次编译器可能会发出一个错误消息,即使用无效参数,因为参数的类型不同,并且没有从一种类型到另一种类型的隐式转换。

,

您可能想要滚动自己的差异函数或为用户提供转换运算符,该运算符将允许set_difference比较对和用户。

set_difference需要相互转换,并且能够将Type1插入输出序列。使用std::map不能进行相互转换,因为在这种情况下转换运算符必须是std::pair的成员。

,

set_difference的比较器 cmp LessCompare ,并且将使用 像这样:

 pair<int,int> e == User u <==> !(e < u) && !(u < e) <==> !cmp(e,u) && !cmp(u,e)

这仅在 e u 可相互转换的情况下才有效。

,

我相信您的lambda输入参数的顺序错误。请尝试以下一种。

[](const User &u,const std::pair<int,int> &e){ return u.getId() == e.first; });