Reputation: 12583
A program I'm working on contains this predicate struct:
struct Unlike {
Unlike(const Vertex& in) : a(in) {}
bool operator()(const Vertex& b) {
return !(a==b);
}
const Vertex& a;
};
Vertices are structs with (among other members) a struct coord with members X, Y, Z. Comparison is done with these functions:
bool operator==(const Vertex& a, const Vertex& b) {
bool res = a.coord.X == b.coord.X &&
a.coord.Y == b.coord.Y &&
a.coord.Z == b.coord.Z;
return res;
}
inline bool operator!=(const Vertex& a, const Vertex& b) {
bool res = !(a==b);
return res;
}
Which is used like this:
std::vector<Vertex> vertices;
// Fill and sort vertices
std::vector<Vertex>::iterator vcur, vnext;
vcur = vertices.begin();
while(vcur != vertices.end()) {
vnext = std::find_if(vcur, vertices.end(), Unlike(*vcur));
// Loop over [vcur, vnext]
vcur = vnext;
}
So we perform some calculations on all vertices which compare equal.
I'm doing some cleaning in the code, and would like to get rid of the Unlike
struct. I tried to do it like this, which to my mind is clearer in intent:
vnext = std::adjacent_find(vcur, vertices.end(), std::not_equal_to<Vertex>());
but that did not retain the same behavior, but rather goes into an infinite loop. Why? Have I misinterpreted adjacent_find
or not_equal_to
?
Upvotes: 1
Views: 350
Reputation: 78
std::adjacent_find looking ahead for one item and returns iterator if predicate is true.
(1) For example, if you use not_equal_to for the list of two letters ['a','b'] and your current iterator points to 'a' then predicate will be positive because 'a' not equal to the next 'b' and std::adjacent_find returns an iterator which is a reference to 'a'.
(2) in your first version find_if first iterate to 'b' and only then compare 'b' with 'a'. And as result we have an iterator which is a reference to 'b'.
Upvotes: 1