我正在尝试在集合中找到结构的向量。为此,我编写了以下代码:
#include <cstdlib>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
struct A{
int a;
};
int main(int argc, char** argv) {
std::set< std::vector<A> > aObj;
A a1,a2,a3,a4,a5,a6;
a1.a=5; a2.a=8; a3.a=10;
a4.a=5; a5.a=8; a6.a=10;
vector<A> vecA,vecB;
vecA.push_back(a1); vecA.push_back(a2); vecA.push_back(a3);
aObj.insert(vecA);
set< vector<A> >::iterator it = aObj.find(vecB);
if (it != myset.end()) {
cout<<"\n Found vector B. \n";
}
return 0;
}
但是,上面的代码给出了以下错误:
/usr/include/c++/4.6/bits/stl_algobase.h:881:6: error: no match for ‘operator<’ in ‘* __first1 < * __first2’
/usr/include/c++/4.6/bits/stl_algobase.h:881:6: note: candidates are:
/usr/include/c++/4.6/bits/stl_pair.h:207:5: note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
/usr/include/c++/4.6/bits/stl_iterator.h:291:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/stl_iterator.h:341:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/basic_string.h:2510:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2522:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/basic_string.h:2534:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
答案 0 :(得分:4)
另一个答案很好地解释了。如果A
defines a weak total ordering (e.g. by implementing operator<
)您能够找到这些向量。
以下是如何使代码更简洁:
<强> Live On Coliru 强>
#include <iostream>
#include <set>
#include <vector>
struct A {
int a;
bool operator<(A const &other) const { return a < other.a; }
};
int main() {
std::set<std::vector<A> > myset{
{ { 4 }, { 7 }, { 9 } },
{ { 5 }, { 8 }, { 10 } },
{ { 6 }, { 9 }, { 11 } },
};
auto it = myset.find({ {1}, {2}, {3} });
std::cout << "Found vector: " << std::boolalpha << (it != myset.end()) << "\n";
it = myset.find({ {5}, {8}, {10} });
std::cout << "Found vector: " << std::boolalpha << (it != myset.end()) << "\n";
}
打印
Found vector: false
Found vector: true
这为A
使用聚合初始化,vector
和set
容器的统一初始化({a,b,c}
将使用std::initialializer_list<>
构造函数重载)
答案 1 :(得分:3)
就像现在一样,std::set::find
正试图使用std::less<std::vector<A>>
将给定的向量与集合中的向量进行比较,std::set<std::vector<A>>
是bool operator<(const std::vector<A>& lhs, const std::vector<A>& rhs) const
实例的默认比较器。 AFAIK,std :: less将调用std::less<A>
来比较向量,这将依次使用std::less<A>
对向量进行字典比较。然后,bool A::operator<(const A& rhs) const
会尝试调用bool operator<(const A& lhs, const A& rhs) const
(成员函数版本)或A
(自由函数版本)来比较struct A
的实例。这是失败的,因为这些功能都不存在。
您有两种选择:
1)您为bool operator<(const A& rhs) const { return a < rhs.a; }
配备了一个比较运算符(在本例中,我们将其作为成员函数),如下所示:
std::vector
并依赖于operator<
执行std::set
,执行词典比较。字典比较意味着成对地比较矢量元素,直到找到被比较的两个矢量的元素对(x,y),其中x <1。 y或y&lt; X。如果不存在这样的对,则两个向量被认为是相等的,除非它们具有不同的长度,在这种情况下,较短的向量是较长的向量的前缀,并且考虑较少。
2)您为std::vector
提供了一个可以比较矢量的比较器,具体来说,确定两个矢量中哪一个小于另一个。这仅在您不想使用struct VecCmp {
bool operator<(const std::vector<A>& lhs, const std::vector<A>& rhs) const {
// determine whether lhs is less than rhs and return true if so, false otherwise
}
};
的词典编纂比较并且您可以在矢量上定义弱总排序时才有用。如果是这种情况,那么你可以像这样实现一个比较器:
std::set
然后将std::set<std::vector<A>, VecCmp> myset(VecCmp());
配置为使用此比较器,如下所示:
{{1}}