error C2678: binary '==' : no operator found which takes a left-hand operand of type (or there is no acceptable conversion)
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;
}
Andrey Dyatlov
Updated on April 26, 2020Comments
-
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 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'
thatclang
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 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 over 9 yearsRegarding 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 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 over 9 years@WhozCraig I believe it's trying to compare the two
point_xy
s inside the pair, but only finds theoperator==
template for comparingpair
s.