0

I created a set via

bool(*fn_pt)(const double&, const double&) = comp_double;
std::set<double, bool(*)(const double&, const double&) > values(fn_pt);

where my comp_double function is given by

bool comp_double (const double& p1, const double& p2)
{
return (std::abs(p1-p2)<1e-05);
}

I inserted two dummy elements, values.insert(0.01) and values.insert(0.02), but the size of my set is still zero. There are no compiler warnings or errors, so I guess the problem lies within my comp_double function. Any input would be appreciated!

Best

Simon
  • 325
  • 1
  • 6

1 Answers1

1

First, we should remember that a std::set is an associative container (that contains only the "keys"). Yes, we can provide our own comparison operation for an associative container. This operation must conform to strict weak ordering (we can think of it as a "less than"), means to have the following properties:

  • Two keys cannot be both "less than" each other. (Also, a key cannot yield "less" with itself)
  • The comparison has to be transitive. If key1 < key2, key2 < key3, then key1 < key3
  • If we have two keys and neither of these is "less than" the other, they must be equivalent.

Consider this case:

key1 = 0.000001;
key2 = 0.000002;

abs(key1 - key2) == 0.000001; // which is less than 0.00001, true
abs(key2 - key1) == 0.000001; // same, true too

Each of them is "less" than the other, means they violate the first constraint. Also, a key here will yield true for "less" with itself.

You may want to take a look at: Does using epsilon in comparison of floating-point break strict-weak-ordering?

For more on the requirements on a Compare check the documentation.

rawrex
  • 4,044
  • 2
  • 8
  • 24
  • `s/equal/equivalent/` and you miss some constraints. – Jarod42 Jun 28 '21 at 11:09
  • @Jarod42 thanks! May you please specify which? – rawrex Jun 28 '21 at 11:11
  • 2
    There are 4 on [wikipedia](https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings) linked from [cppreference](https://en.cppreference.com/w/cpp/named_req/Compare). – Jarod42 Jun 28 '21 at 11:13
  • Thanks for all your feedback. I thought so that my comparison using std::abs is too simple. However for my purposes as engineer I always compared double values with an epsilon threshold. So can you give me some keywords how my comparison should look like? – Simon Jun 28 '21 at 12:55
  • @Simon you should take a look at this [thread](https://stackoverflow.com/questions/68114060/does-using-epsilon-in-comparison-of-floating-point-break-strict-weak-ordering) if you haven't yet seen it. Especially this [answer](https://stackoverflow.com/a/68114287/14624729). Feel free to comment or initiate a fresh question on the topic. – rawrex Jun 28 '21 at 13:01