carlpett
carlpett

Reputation: 12583

Reformulate custom predicate as std-predicate

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

Answers (1)

Mazurov
Mazurov

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

Related Questions