我有一个复杂的结构,我想把它作为std :: map的一个关键字来快速列出所有独特的对象:
union somecomplexstruct {
struct {
more_structs val1, val2;
even_more_structs val3, val4;
lots_of_more_structs val5;
};
unsigned int DATA[3];
};
typedef map<somecomplexstruct, int, greater<somecomplexstruct> > somecomplexstructMap;
但它说错误:error C2784: 'bool std::operator >(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const somecomplexstruct'
如何让我的结构在那里工作?
编辑:让大家工作,谢谢大家!下面是代码:
inline bool operator>(const somecomplexstruct &v1, const somecomplexstruct &v2){
if(v1.DATA[0] > v2.DATA[0]) return 1;
if(v1.DATA[0] < v2.DATA[0]) return 0;
if(v1.DATA[1] > v2.DATA[1]) return 1;
if(v1.DATA[1] < v2.DATA[1]) return 0;
return v1.DATA[2] > v2.DATA[2];
}
答案 0 :(得分:9)
std::greater<>
调用operator>()
来完成其工作,因此如果您想使用std::greater<>
,则需要重载该工作。
它应该是这样的:
inline bool operator>(const somecomplexstruct& lhs, const somecomplexstruct& rhs)
{
// implement your ordering here.
}
答案 1 :(得分:3)
使用operator>
功能,考虑如果您比较{1, 0, 0}
和{0, 1, 0}
会发生什么。如果比较a > b
,则从第一次比较中返回true。如果比较b > a
,则从第二次比较中返回true。因此,它没有用于比较的反身属性,扰乱了地图。为了使地图正常工作,您必须定义运算符&gt;对于可能被比较的所有可能的非等值值,a > b
== !(b > a)
。
修改强>
确保运算符正确反射的最简单/最好的方法是确保每个可能返回true的测试,您还有一个具有相同条件的测试,并且交换的操作数返回false。 所以,如果你有
if(v1.DATA[1] > v2.DATA[1]) return 1;
在你的功能中,你需要
if(v2.DATA[1] > v1.DATA[1]) return 0;
或等同于某处。
答案 2 :(得分:2)
这是复杂结构的词典比较
struct D {
struct A {
bool operator <(const A &) const;
} a;
struct B {
bool operator <(const B &) const;
} b;
struct C {
bool operator <(const C &) const;
} c;
template <class T> ne(const T & a, const T & b) {
if (a < b) return true;
if (b < a) return true;
return false;
}
bool operator < (const D & that) const {
if (ne(a, that.a)) return a < that.a;
if (ne(b, that.b)) return b < that.b;
return c < that.c;
}
};
答案 3 :(得分:0)
如果您的地图仅包含指向结构的指针,则不必执行所有复杂的运算符重载。
因此你的typedef如下所示:
typedef map<somecomplexstruct*, int, greater<somecomplexstruct*> > somecomplexstructMap;
结构通常只有公共数据成员,不需要运算符重载。
这意味着您必须注意何时以及如何释放指针的内存。每种方法都有利有弊,就像所有方法一样。