以下代码引发编译错误
class A
{
public:
A(int i):a(i){}
int a;
};
int main()
{
std::vector<A> As;
As.push_back(A(1));
As.push_back(A(2));
As.push_back(A(3));
As.push_back(A(4));
As.push_back(A(5));
std::vector<int> Is = {2,4};
std::vector<int> Bs = {1,2,3,4,5};
std::vector<A> intersection;
std::set_intersection
(
As.begin(), As.end(),
Is.begin(), Is.end(),
std::back_inserter(intersection),
[](int const& lhs, A const& rhs)
{
return lhs < rhs.a;
}
);
}
错误:如果(__comp(* __ first1,* __ first2))
,则无法调用匹配类型为'(c.cpp:33:4)的对象的对象的匹配函数
我无法为此std::set_intersection
的比较器实现lambda函数。我还尝试重载类operator>
中的operator<
,operator==
和A
,但是仍然失败。你能帮我吗?
答案 0 :(得分:3)
这里的问题是,比较函数在两个方向上都被调用,一次使用(A,int),一次使用(int,A)。我没有检查实现,也许预期这两种类型是相同的。
作为解决方案,您只需提供两个签名即可:
class A
{
public:
A(int i):a(i){}
int a;
};
// Helper to get Lambda with multiple signatures in place
// template deduction guide is a C++17 feature!
template<class... Ts> struct funcs : Ts... { using Ts::operator()...; };
template<class... Ts> funcs(Ts...) -> funcs<Ts...>;
// if c++17 is not available, you have to write a functor/function
// with both signatures
int main()
{
std::vector<A> As;
As.push_back(A(1));
As.push_back(A(2));
As.push_back(A(3));
As.push_back(A(4));
As.push_back(A(5));
std::vector<int> Is = {2,4};
std::vector<int> Bs = {1,2,3,4,5};
std::vector<A> intersection;
std::set_intersection
(
As.begin(), As.end(),
Is.begin(), Is.end(),
std::back_inserter(intersection),
funcs{
[](A const& lhs, int const& rhs)
{
return lhs.a < rhs;
},
[](int const& lhs, A const& rhs)
{
return lhs < rhs.a;
}
}
);
}
我在fedora上的g ++(GCC)8.1.1 20180712(Red Hat 8.1.1-5)下运行此文件。如果我仅提供一个签名,而与首先使用int或A无关,那么我会收到错误消息:
1)
no match for call to '(main()::<lambda(const A&, const int&)>) (int&, A&)'
或
2)
no match for call to '(main()::<lambda(const int&, const A&)>) (A&, int&)'
因此需要提供一个在此处接受两个签名的comp函数。
答案 1 :(得分:0)
在@Klaus建议使用仿函数的情况下,这是使用仿函数的有效示例。
class A
{
public:
A(int i):a(i){}
int a;
};
class comparatorsForSetIntersection
{
public:
bool operator()(int lhs, A rhs) {return lhs + rhs.a;}
bool operator()(A lhs, int rhs) {return lhs.a + rhs;}
};
int main()
{
std::vector<A> As;
As.push_back(A(1));
As.push_back(A(2));
As.push_back(A(3));
As.push_back(A(4));
As.push_back(A(5));
std::vector<int> Is = {2,4};
std::vector<int> Bs = {1,2,3,4,5};
std::vector<A> intersection;
comparatorsForSetIntersection comps;
std::set_intersection
(
As.begin(), As.end(),
Is.begin(), Is.end(),
std::back_inserter(intersection),
comps
);
}