Ch3shire Ch3shire - 14 days ago 7
C++ Question

C++: find() with custom == operator

I have a case where apparently no operator== is defined for external class and I need to use a find() function. I know I could do this step by step, but I wonder - is there a way to define custom == operator for this find function, similar how we define Hash function for unordered_set? The case:

#include <vector>
#include <algorithm>
#include <MathGeoLib/Math/float3.h>

bool operator==(const math::float3 &lhs, const math::float3 &rhs){
return lhs.x == rhs.x;
}

int main(){
std::vector<math::float3> V;
...
std::find(V.begin(),V.end(),math::float3(0,0,0));
}


returns

binary '==': no operator found which takes a left-hand operand of type math::float3' (or there is no acceptable conversion)


Sometimes I would like to find not exact same vector, but vector close enough - here I would just override
operator==
with more suitable. Is there any smart way to do that?

Answer

You can use std::find_if, here is an example where value_type is double. The function cmp compares for exact equality, and cmp_epsilon compares for equality within some epsilon.

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>

bool cmp(double a, double b)
{
    return a == b;
}

bool cmp_epsilon(double e, double a, double b)
{
    return a + e >= b and a - e <= b;
}

using namespace std::placeholders;

int main() {
    std::vector<double> A = {3./2, 2, 1};

    auto i1 = std::find_if(A.begin(),A.end(),std::bind(cmp, 61./40., _1));
    std::cout << std::distance(A.begin(), i1) << std::endl;

    auto i2 = std::find_if(A.begin(),A.end(),std::bind(cmp_epsilon, 0.1, 61./40., _1));
    std::cout << std::distance(A.begin(), i2) << std::endl;
}