2014-10-09 41 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

相關問題