附加使用 Struct 作为 "multikey" 和 std::vector 作为映射值的映射

Appending map that uses Struct as a "multikey" and std::vector as mapped value

在下面的代码中,它仅在第一次调用 appendMyList() 时附加 myList,并且大小保持为 1,所以有人可以解释这里的错误:

struct MyKey {
  int accValue;
  std::string name;
};

inline bool operator<(MyKey a, MyKey b){
  return a.accValue < b.accValue && a.name < b.name;
}

inline bool operator==(MyKey a, MyKey b){
  return a.accValue == b.accValue && a.name == b.name;
}

typedef std::map<MyKey, std::vector<int>> MyList;

class MyClass {
    public:
    void appendMyList(int accVal, std::string name, int element) {
        myList[MyKey{accVal, name}].push_back(element);
        cout<<endl<<"Size after"<< myList.size()<<endl;
    }

   MyList myList;
};

我看到了类似的 post 但我的运算符没有发现任何问题,所以我猜是其他原因?

我是这样调用函数的:

int main()
{
    MyClass imHere;
    int a = 1;
    std::string yaya = "name";
    for (int i = 0; i<10; i++) {
            imHere.appendMyList((++a), yaya, i);
    }

    return 0;
};

std::map 不允许存储重复项。但是,它不使用 operator== 来检查元素的 相等性 。它对两者都使用 operator< -- 排序元素以及检查 equivalence.

也就是说,如果 !(a < b) && !(b < a) 那么 std::map 认为 ab 等价,因此使用 operator< 插入的元素不会超过一个,因为 name 在所有元素中都相同,因此 (a < b)(b < a) return false.

相反,您应该使用:

inline bool operator<(MyKey a, MyKey b) {
  return a.accValue < b.accValue || (a.accValue == b.accValue && a.name < b.name);
}

或:

inline bool operator<(MyKey a, MyKey b) {
  return std::tie(a.accValue, a.name) < std::tie(b.accValue, b.name);
}