使用自定义结构作为键类型访问std :: map会导致奇怪的行为

ron*_*ine 2 c++ stl c++11

我试图用简单的自定义键访问std :: map,但是大多数情况下这是有效的,每隔一段时间,根据给定的值,它将无法访问映射的值.

在这里,我烘焙了一个测试程序,它更详细地显示了这个问题:

 #include <map>
 #include <cstdint>
 #include <cassert>

 struct key_type
 {
   uint32_t       a;
   uint32_t       b;

   bool operator<(const key_type& value) const
   {
     if (value.a < a)
       return true;

     if (value.b < b)
       return true;

     return false;
   } 

   key_type(uint32_t a, uint32_t b) : a(a), b(b)
   {}
 };

 std::map<key_type, int*> test;

 int get_int(uint32_t a, uint32_t b)
 {
   if (test.count(key_type(a, b)) == 0)
   {
     int* r = new int;
     assert(r != nullptr);

     key_type key = key_type(a, b);
     test[key] = r;

     assert(test[key] != nullptr);
   }
   return *test[key_type(a,b)];
 }
Run Code Online (Sandbox Code Playgroud)

现在我尝试用两组不同的参数调用get_int.第一种情况按预期工作.

 int main(int argc, char* argv[])
 {
    get_int(2, 4);
    get_int(3, 4);
    get_int(4, 5);
    get_int(2, 1);
    get_int(120, 1);

    return 0;
 }
Run Code Online (Sandbox Code Playgroud)

现在,如果我稍微改变一组值,一切都会爆炸.

 int main(int argc, char* argv[])
 {
    get_int(2, 4);
    get_int(3, 4);
    get_int(4, 5);
    get_int(120, 1);

    return 0;
 }
Run Code Online (Sandbox Code Playgroud)

"assert(test [key]!= nullptr);" 失败.虽然我可以规避实际问题,但我想知道在这个表面下会发生什么导致这种行为?

Ami*_*ory 6

你的比较运算符没有多大意义.补充

(value.a < a)
Run Code Online (Sandbox Code Playgroud)

还包括案例value.a > a.

如果你创建比较运算符的整个主体:

return std::make_pair(a, b) < std::make_pair(value.a, value.b);
Run Code Online (Sandbox Code Playgroud)

更好的是使用std::tie:

return std::tie(a, b) < std::tie(value.a, value.b);
Run Code Online (Sandbox Code Playgroud)