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

35,280

The reason why this fails is that the operator == for std::pair uses == to compare the pairs' members, which in turn uses argument-dependent lookup (ADL) to find the proper operator == for them. But you've provided the overload in the wrong namespace, since Point is actually a typedef for something in ::boost::geometry::model::d2, and not in ::.

If you move the operator into the correct namespace (which is a good idea anyway), it works:

#include <boost/geometry/geometries/point_xy.hpp>

#include <iostream>
#include <utility>

typedef boost::geometry::model::d2::point_xy<long> Point;
typedef std::pair<Point, Point> Vector;

namespace boost { namespace geometry { namespace model { namespace d2 {

bool operator==(const Point& p1, const Point& p2) {
  return p1.x() == p2.x() && p1.y() == p2.y();
}

} } } }


int main() {
    Vector vec1(Point(0,0), Point(1,1));
    Vector vec2(Point(0,0), Point(1,2));
    std::cout << ((vec1 == vec2) == false) << std::endl;
    std::cout << ((vec1 == vec1) == true) << std::endl;
}

Live example

Share:
35,280
Andrey Dyatlov
Author by

Andrey Dyatlov

Updated on April 26, 2020

Comments

  • Andrey Dyatlov
    Andrey Dyatlov about 4 years

    I'm trying to compile the following code:

    #include <boost/geometry/geometries/point_xy.hpp>
    
    #include <iostream>
    #include <utility>
    
    typedef boost::geometry::model::d2::point_xy<long> Point;
    typedef std::pair<Point, Point> Vector;
    
    bool operator==(const Point& p1, const Point& p2) {
      return p1.x() == p2.x() && p1.y() == p2.y();
    }
    
    int main() {
        Vector vec1(Point(0,0), Point(1,1));
        Vector vec2(Point(0,0), Point(1,2));
        std::cout << ((vec1 == vec2) == false) << std::endl;
        std::cout << ((vec1 == vec1) == true) << std::endl;
    }
    

    VS2012 C++ compiler returns the following compilation error:

    ...VC\include\utility(219): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const Point' (or there is no acceptable conversion)

    GCC C++ compiler returns the following compilation error:

    /usr/include/c++/4.8/bits/stl_pair.h:

    In instantiation of ‘bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) [with _T1 = boost::geometry::model::d2::point_xy; _T2 = boost::geometry::model::d2::point_xy]’:

    test.cpp:22:28: required from here /usr/include/c++/4.8/bits/stl_pair.h:215:51: error:

    no match for ‘operator==’ (operand types are ‘const boost::geometry::model::d2::point_xy’ and ‘const boost::geometry::model::d2::point_xy’) { return __x.first == __y.first && __x.second == __y.second; }

    Error disappears if I overload == operator for Vector:

    bool operator==(const Vector& v1, const Vector& v2) {
        return v1.first == v2.first && v1.second == v2.second;
    }
    
  • WhozCraig
    WhozCraig over 9 years
    +1 I concur, Can you add an addendum explaining the seemingly rather cryptic error message: Candidate template ignored: could not match 'pair' against 'point_xy' that clang chooses to bless us with? I.e. How did that expression give us that mismatched comparison? Why did ADL miss one and not the other (or did it miss both) ?
  • David Rodríguez - dribeas
    David Rodríguez - dribeas over 9 years
    @WhozCraig: unqualified lookup found the operator== that involves two pairs, ADL did not find any additional overloads. The compiler (clang) is telling you: I cannot use this one, and I don't know of any other.
  • David Rodríguez - dribeas
    David Rodríguez - dribeas over 9 years
    Regarding the proposed solution, I don't quite like the idea of adding code to a namespace you don't own. Rather than adding the operator I would try to find out what alternative the library proposes (I would not expect that to be an oversight on the library, but intentionally left aside for some reason that escapes me). By adding code to their library you are risking breaking with the next update (what if they add the operator in the future?) and undefined behavior (what if two translation units see/don't see the operator, or see different versions?) I'd create a named function instead.
  • WhozCraig
    WhozCraig over 9 years
    @DavidRodríguez-dribeas I likely didn't ask the right question. I know that ADL didn't find a matching equivalence operator. What i was trying to ask was the why the specific types in the resulting error message were reported. Neither item on that comparison is a simple point_xy, either in the call or in the implementation.
  • Angew is no longer proud of SO
    Angew is no longer proud of SO over 9 years
    @WhozCraig I believe it's trying to compare the two point_xys inside the pair, but only finds the operator== template for comparing pairs.