【问题标题】:std::map use. What is wrong here ? core dump ? What I do not do correctly?std::map 使用。这里有什么问题?核心转储?我做错了什么?
【发布时间】:2019-04-12 21:09:35
【问题描述】:

这里有什么问题?核心转储?我做错了什么?

#include <cstdio>
#include <map>
#include <cmath>
#include <cstring>
#include <iostream>

bool compFloats (const float f1, const float f2){
  return floor (f1) < floor (f2);
};

int main (int argc, char **argv){

  std::map < float, char, decltype (&compFloats) > m;


  m.emplace (3.9, 'a');
  m.emplace (3.1, 'b');
  m.emplace (4.1, 'c');
  m.emplace (4.5, 'd');
  m.emplace (5.2, 'e');

  for (auto i = m.begin (); i != m.end (); i++)
    printf ("%c ", i->second);
  printf ("\n");


  printf ("hello world\n");

  return 0;
}

【问题讨论】:

  • 您可能会更加好奇,并删除了 map 声明中的第三个模板参数,以查看结果是否发生变化。
  • 有语法错误,还是逻辑错误?它在第二次执行 emplace 时转储。
  • 好吧,照我说的做。删除第三个模板参数,重建/重新运行您的应用程序。如果它没有崩溃,那么可能会在您的问题中添加更多关于您观察到的内容?由于“缺乏研究”,您即将投反对票。
  • 当第三个参数被取消时,比较不同并且程序可以工作。
  • 既然你已经完成了,这一切都应该在你发布之前完成。然后在问题中,您可以说“当我删除第三个参数时,我的程序不再崩溃。第三个参数中的什么会导致这种情况?”。这将是一种更好的方式来提出问题,而不是像你最初所做的那样。

标签: c++


【解决方案1】:

假设您的自定义比较运算符是此代码运行所必需的,您面临的问题是传递给地图模板的参数decltype (&amp;compFloats) 没有描述特定功能您想用作比较器,而是该函数的类型名。结果,当 map 尝试执行比较时,它没有任何具体的函数可供使用,并且可能在某处取消引用空指针,从而导致核心转储。

如果您确实需要这种比较(浮点值在保存之前被四舍五入到最接近的整数),您需要像这样定义映射,使用本地 struct 可以比较floats:

struct CompFloat {
    bool operator()(float a, float b) const {
        return floor(a) < floor(b);
    }
};

int main() {
    std::map<float, char, CompFloat> m;
    //...
}

或者,如果您只需要使用 std::mapfloats 作为键,并且截断无关紧要(或不必要/无用),则只需编写此代码即可。

int main() {
    std::map<float, char> m;
    //...
}

这将满足您的期望。

【讨论】:

  • std::map &lt; float, char, decltype (&amp;compFloats) &gt; m(compFloats); - 问题解决了。
  • @LogicStuff 如果您更喜欢将其作为解决方案,欢迎您将其发布为对此问题的自我回答。
【解决方案2】:

根据@Xirema 的初步迹象,我尝试了“预期语法”

代替:

std::map < float, char, decltype (&compFloats) > m;

我把它初始化为:

std::map<float,char,decltype(&floatComp)> m(&floatComp);

我不知道它写在文档的什么地方,但现在可以正常工作了!!!

【讨论】:

    【解决方案3】:

    为了更好地理解映射的类和对象之间的区别,代码如下定义两个具有相同类型但不同比较函数的映射。

    #include <cstdio>
    #include <map>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    
    bool comp1(const float f1,const float f2)   {return floor(f1)<floor(f2);}
    bool comp2(const float f1,const float f2) {return f1-floor(f1)<f2-floor(f2);}
    
    typedef bool (*comp_t)(const float,const float);
    typedef std::map<float,char,comp_t> M;
    
    int main(int argc, char **argv)
    {   
            M m1(&comp1);
            M m2(&comp2);
    
            m1.emplace(3.9,'a');m2.emplace(3.9,'a');
            m1.emplace(3.1,'b');m2.emplace(3.1,'b');
            m1.emplace(4.1,'c');m2.emplace(4.1,'c');
            m1.emplace(4.5,'d');m2.emplace(4.5,'d');
            m1.emplace(5.2,'e');m2.emplace(5.2,'e');
    
        for (auto i=m1.begin();i!=m1.end();i++)
            printf("%c ",i->second);
        printf("\n");
    
        for (auto i=m2.begin();i!=m2.end();i++)
            printf("%c ",i->second);
        printf("\n");
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 2013-06-28
      • 2023-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多