Consider this code:
#include <vector>
#include <iostream>
#include <cstdint>
#include <ranges>
int main()
{
struct S {
int a;
int b;
bool operator==(int other) const { return a == other; }
};
std::vector<S> iv{
{1, 2},
{3, 4}
};
// this works
if (auto const it{std::find(iv.begin(), iv.end(), 1)}; it != iv.end()) {
std::cout << "Found!n" << "n";
}
//std::ranges::find(iv, 2); // <-- why does this not compile
}
My impression was that the call convention of ranges would be a 1-to-1 mapping of the corresponding original algorithm (i.e., just skip the .begin() and .end(), and it should work as before).
Clearly this is not the case here. What am I missing?
A link to the code:
https://godbolt.org/z/3a6z9c5of
0
1 Answer
ranges::find uses ranges::equal_to by default to compare the elements of the range with the value, and the call operator of ranges::equal_to constrains the two types to satisfy equality_comparable_with, which is S and int in your example.
equal_comparable_with requires S to be comparable with itself and needs to have a common reference with const int&, which is not your case.
The simple workaround is to use the projection function to project S to S::a
if (auto const it{std::ranges::find(iv, 1, &S::a)}; it != iv.end()) {
std::cout << "Found!n" << "n";
}
6
-
1
What is the motivation for
equality_comparable_withto require the existence of a common reference? What does it have to do with comparison?– Evg11 hours ago
-
1
-
Thanks. Unfortunately, the answer there doesn't really explain the motivation, "the design says", that's all. I guess I need to study the document that answer refers to.
– Evg10 hours ago
-
3
@Evg Well, what does it even mean to say that an
S(a type with twoints in it) is "equal" to anint? There are certain properties that we think about when we think about equality… soS{1, 2} == 1andS{1, 3} == 1, does that imply thatS{1, 2} == S{1, 3}? ButSisn't even comparable to itself, so what can we even meaningfully say about this? This example strikes me more like it's using==for the syntactic convenience offindmore than anything else.– Barry10 hours ago
-
@Evg: motivation of constraints are to have meaningful contraints, i.e just have
operator<(for ordering) is "strange" (so nooperator >) (even if it is indeed the "old" C++ way).– Jarod4210 hours ago

