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

时间:2016-11-25 13:56:16

标签: c++ c++11 find operator-overloading

我有一个案例,显然没有为外部类定义operator ==我需要使用find()函数。我知道我可以一步一步地做到这一点,但我想知道 - 有没有办法为这个查找函数定义自定义==运算符,类似于我们如何为unordered_set定义哈希函数?案例:

#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));
}

返回

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

有时候我想找到不完全相同的向量,但是矢量足够接近 - 在这里我会用更合适的方式覆盖operator==。有没有聪明的方法呢?

3 个答案:

答案 0 :(得分:4)

您可以使用std::find_if,这是value_typedouble的示例。 函数cmp比较精确相等,cmp_epsilon比较某些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;
}

答案 1 :(得分:2)

为清楚起见,我将实现一个自定义查找函数,该函数接受比较元素的方法:

template<class InputIt, class Compare, class T>
InputIt custom_find(InputIt first, InputIt last, Compare comp, const T& value)
{
    for (; first != last; ++first) {
        if (comp(*first, value)) {
            return first;
        }
    }
    return last;
}

然后,您可以将==运算符的正文作为lambda提供给custom_find

int main(){
    std::vector<math::float3> V;
    ...
    custom_find(V.begin(), V.end(), 
             [] (const auto& lhs, const auto& rhs) { return your_way_to_compare(lhs,rhs); }, 
             math::float3(0,0,0));
}

答案 2 :(得分:2)

使用operator==除了完全平等之外的其他任何东西都在玩火:没有人会期待它,甚至在几天/几周内都没有。

尽管如此,您的问题可能是由于名称查找。

在C ++中,您应该在其参数的一个的命名空间中声明自由函数。在这种情况下,您应该在operator==命名空间中定义math

简而言之,这是因为编译器开始在参数的命名空间中查找正确的重载,并且一旦找到包含某些函数的命名空间就停止收集更多重载以进行检查...因此它永远不会检查全局命名空间。