简体   繁体   English

如何在std :: map中使用struct?

[英]How to use a struct in std::map?

I have a complex struct i want to put as a key of the std::map to make a list of all unique objects fast: 我有一个复杂的结构,我希望将其作为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;

But it says error: 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' 但它说错误: 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'

How do i make my struct work there? 我如何使我的结构在那里工作?

Edit: Got it working, thanks to everyone! 编辑:得到它的工作,感谢大家! Heres the code: 下面是代码:

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];
}

std::greater<> invokes operator>() to do its work, so you need to overload that if you want to use std::greater<> . std::greater<>调用operator>()来完成它的工作,所以如果你想使用std::greater<> ,你需要重载它。

It should look like this: 它应该如下所示:

inline bool operator>(const somecomplexstruct& lhs, const somecomplexstruct& rhs)
{
  // implement your ordering here. 
}

With your operator> function, consider what happens if you compare {1, 0, 0} and {0, 1, 0} . 使用operator> function,考虑如果比较{1, 0, 0}{0, 1, 0} {1, 0, 0}会发生什么。 If you compare a > b , it returns true from the first comparison. 如果比较a > b ,则从第一次比较中返回true。 If you compare b > a it returns true from the second comparison. 如果比较b > a ,则从第二次比较中返回true。 So its fails the reflexive property for comparisons, scrambling the map. 因此,它没有用于比较的反身属性,扰乱了地图。 In order for map to work properly, you must define your operator> such that a > b == !(b > a) for all possible non-equal pairs of values that might be compared. 为了使映射正常工作,您必须定义运算符>使得a > b == !(b > a)可以比较所有可能的非等值值。

edit 编辑

The easiest/best way to ensure that your operator is properly reflexive is to ensure the for every test that might return true, you also have a test with the same condition and the operands swapped that returns false. 确保操作符正确反身的最简单/最好的方法是确保每个可能返回true的测试,您还有一个具有相同条件的测试,并且交换的操作数返回false。 So if you have 所以,如果你有

if(v1.DATA[1] > v2.DATA[1]) return 1;

in your function, you need 在你的功能中,你需要

if(v2.DATA[1] > v1.DATA[1]) return 0;

or the equivalent somewhere. 或等同于某处。

Here is lexicographical comparator for a complex structure 这是一个复杂结构的词典比较器

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;
  }
};

If your map contains only pointers to your struct, you don't have to do all that complicated operator overloading. 如果您的地图仅包含指向结构的指针,则不必执行所有复杂的运算符重载。

Therefore your typedef looks like this: 因此你的typedef看起来像这样:

typedef map<somecomplexstruct*, int, greater<somecomplexstruct*> > somecomplexstructMap;

Structs typically have only public data members and no need for operator overloading. 结构通常只有公共数据成员,不需要运算符重载。

This means though that you have to be careful about when and how you release the memory for the pointers. 这意味着你必须要小心何时以及如何释放指针的内存。 There's pros and cons to each approach, as with everything. 每种方法都有各自的优点和缺点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM