-1

What is wrong here ? core dump ? What I do not do correctly?

#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;
}
George Kourtis
  • 2,381
  • 3
  • 18
  • 28
  • 2
    You could have been a little more curious and removed the third template argument in your `map` declaration to see if the results change. – PaulMcKenzie Apr 12 '19 at 21:13
  • There is any syntax error, or logic one ? it dumps at the second execution of emplace. – George Kourtis Apr 12 '19 at 21:16
  • Well, do as I stated. Remove the third template argument, rebuild / rerun your application. If it doesn't crash, then maybe add more to your question as to what you observed? You're getting close to having a downvote due to "lack of research". – PaulMcKenzie Apr 12 '19 at 21:17
  • When the third argument is taken off the comparison is different and the program works. – George Kourtis Apr 12 '19 at 21:20
  • Now that you've done that, this should have all been done before you posted. Then in the question, you could have stated "when I remove the third parameter, my program no longer crashes. What is in the third parameter that would cause this?". That would have been a much better way to present the question, not as you originally had done. – PaulMcKenzie Apr 12 '19 at 21:22
  • in that Q&A the third argument is a class: https://stackoverflow.com/questions/5733254/how-can-i-create-my-own-comparator-for-a-map. And removing this argument probably does the same thing as your code is trying to do since you're just comparing floats in a natural way. – Jean-François Fabre Apr 12 '19 at 21:22

3 Answers3

3

Starting with the assumption that your custom-built comparison operator is necessary for this code to function, the issue you're facing is that the argument being passed to the map template, decltype (&compFloats), doesn't describe the specific function you want to use as a comparator, but rather the typename of that function. As a result, when the map attempts to perform comparisons, it doesn't have any concrete function to use, and probably dereferences a null pointer somewhere, causing the core dump.

If you actually need this kind of comparison (where the floating point values are being rounded down to the nearest integer before being saved), you'll need to define the map like this instead, using a local struct that can compare floats together:

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

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

Alternatively, if what you need is just to use a std::map with floats as the key, and the truncation is immaterial (or unnecessary/unhelpful), just write this instead.

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

This will do what you probably expect of it.

Xirema
  • 19,889
  • 4
  • 32
  • 68
0

Based on the preliminary indications of @Xirema I tried an "expected syntax"

instead of:

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

I initialized it as:

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

I don't know where in the documents it is written but now works correctly as expected !!!

George Kourtis
  • 2,381
  • 3
  • 18
  • 28
0

The code to understand better the difference between class and object of a map follows by defining two maps with the same type but different comparison functions.

#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;
}
George Kourtis
  • 2,381
  • 3
  • 18
  • 28