【问题标题】:error C2678: binary '==' : no operator found which takes a left-hand operand of type (or there is no acceptable conversion)错误 C2678:二进制“==”:未找到采用左操作数类型的运算符(或没有可接受的转换)
【发布时间】:2014-12-04 02:20:15
【问题描述】:

我正在尝试编译以下代码:

#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 take a left-hand 'const Point' 类型的操作数(或没有可接受的转换)

GCC C++ 编译器返回以下编译错误:

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

在 '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: 从这里需要 /usr/include/c++/4.8/bits/stl_pair.h:215:51: 错误:

“operator==”不匹配(操作数类型为“const boost::geometry::model::d2::point_xy”和“const boost::geometry::model::d2::point_xy”) { 返回 __x.first == __y.first && __x.second == __y.second; }

如果我为 Vector 重载 == 运算符,错误就会消失:

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

【问题讨论】:

  • @WhozCraig 是的,因为== 是由标准库为std::pair 定义的。
  • @WhozCraig:如果 ADL 找到了比较 Point 对象的运算符,则无需为 Vectors 提供 operator==。

标签: c++ templates operator-overloading boost-geometry


【解决方案1】:

失败的原因是std::pair 的operator == 使用== 来比较对的成员,而后者又使用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

【讨论】:

  • +1 我同意,您能否添加一个附录来解释看似相当神秘的错误消息:Candidate template ignored: could not match 'pair' against 'point_xy' clang 选择祝福我们? IE。这个表达式是如何给我们那个不匹配的比较的?为什么 ADL 错过了一个而不是另一个(或者它错过了 both)?
  • @WhozCraig:不合格的查找找到了涉及两对的operator==,ADL 没有发现任何额外的重载。编译器(clang)告诉你:我不能用这个,我不知道还有其他的。
  • 关于建议的解决方案,我不太喜欢将代码添加到您不拥有的名称空间的想法。我不会添加操作员,而是尝试找出图书馆提出的替代方案(我不认为这是对图书馆的疏忽,但出于某种我无法理解的原因故意将其搁置一旁)。通过将代码添加到他们的库中,您可能会面临下一次更新(如果他们将来添加操作符怎么办?)和未定义的行为(如果两个翻译单元看到/看不到操作符,或者看到不同的版本怎么办?)我会创建一个命名函数。
  • @DavidRodríguez-dribeas 我可能没有问对问题。我知道 ADL 没有找到匹配的等价运算符。我想问的是为什么报告了结果错误消息中的特定types。 无论是在调用中还是在实现中,该比较中的两个项都不是简单的point_xy。
  • @WhozCraig 我相信它试图比较这对中的两个point_xys,但只找到用于比较pairs 的operator== 模板。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 2011-12-09
  • 2015-11-18
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
相关资源
最近更新 更多