2014-10-09 208 views
8

我试图编译下面的代码: 错误C2678:二进制“==”:没有操作员发现这需要类型的左边的操作数(或没有可接受的转化率)

#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++编译器返回以下编译错误:

...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++编译器返回以下编译错误:

/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; }

错误消失,如果我重载==操作符的矢量:

bool operator==(const Vector& v1, const Vector& v2) { 
    return v1.first == v2.first && v1.second == v2.second; 
} 
+4

@WhozCraig是的,因为''==为'标准定义:: pair'由标准库。 – Angew 2014-10-09 08:28:57

+0

@WhozCraig:如果比较'Point'对象的运算符已经被ADL找到,那么就不需要为'Vector'提供'operator =='。 – 2014-10-09 08:46:57

回答

11

之所以失败就是operator ==std::pair使用==到对成员,并且是使用argument-dependent lookup (ADL)找到合适operator ==比较为他们。但是您提供了错误名称空间中的重载,因为Point实际上是::boost::geometry::model::d2中的某个东西的typedef,而不是::

如果移动运营商到正确的命名空间(这是一个很好的想法),它的工作原理:

#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

+0

+1我同意,你可以添加一个附录,解释看似相当隐秘的错误信息:'候选模板被忽略:无法匹配'clang'选择与我们保持联系的'point_xy''对吗?即那个表达式是如何给我们*那个不匹配的比较?为什么ADL错过一个而不是另一个(或者错过了*两个*)? – WhozCraig 2014-10-09 08:42:53

+1

@WhozCraig:不合格的查找发现涉及两对的'operator ==',ADL没有发现任何额外的重载。编译器(clang)告诉你:我不能使用这个,我不知道其他的。 – 2014-10-09 08:48:44

+3

关于提出的解决方案,我不太喜欢将代码添加到不拥有*的命名空间的想法。我不想增加操作员,而是试图找出图书馆提出的替代方案(我不希望这是对图书馆的疏忽,而是故意搁置在一边,因为某些原因逃离了我)。通过将代码添加到库中,您冒着打破下一次更新的风险(如果他们将来会添加运算符会怎么样?)以及未定义的行为(如果两个翻译单元看到/看不到操作员或看到不同的版本会怎么样?)我会创建一个命名函数。 – 2014-10-09 08:54:32

相关问题