试图找到两组点的交集,错误 "No viable overloaded '=' "

Attempting to find the intersection of two sets of Points, error "No viable overloaded '=' "

我目前正试图在 C++ 中找到两个有序点集的交集。我尝试使用 STL set_intersection,但出现错误:"No viable overloaded '='"

然后我尝试编写我自己的 set_intersection 版本,称为我的set_intersection,以便我可以深入研究这个问题。我收到相同的错误消息,只有当我单击它时才会显示另一条错误消息:"Candidate function not viable: 'this' argument has type 'const std::__1::__tree_const_iterator *, long>::value_type' (aka 'const Point'), but method is not marked const".

我在下面包含了我的观点 class,以及重载赋值运算符和我的set_intersection.

非常感谢任何帮助。

struct Point{
    int x;
    int y;

    Point& operator=(const Point& p)  //Candidate function not viable...
    {
        x = p.x;
        y = p.y;
        return *this;
    }
};

using Iterator = set<Point,Point_order>::iterator;
Iterator myset_intersection(Iterator first1, Iterator last1, Iterator first2, Iterator last2, Iterator output)
{
    while(first1 != last1 && first2 != last2)
    {
        if(point_compare(*first1, *first2))
            ++first1;

        else{
            if(!(point_compare(*first2,*first1)))
            {
                *output = *first1;  //No viable overloaded '='
                ++output;
                ++first1;
            }
            ++first2;
        }
    }
    return output;
}

struct Point_order{
    bool operator()(const Point& a, const Point& b) const
    {
        if(a.x == b.x) return a.y < b.y;
        return a.x < b.x;
    }
};


您正在尝试分配给 const Point

不能通过迭代器更改集合的元素。集合(和映射)是通过红黑树实现的,元素在树中的位置取决于键的值(集合只有键)。如果您可以修改密钥,树将必须检测到这一点并重新排列自身,否则它会崩溃。

即使std::set<Point>有一个单独的iterator和一个const_iteratorstd::set<Point>::iterator::operator*()的数据类型(*output的结果)是const Point.

自 1998 年以来一直如此 (https://cplusplus.github.io/LWG/issue103)

如果您想要 Point 类型的输出参数,请使用引用,而不是集合迭代器。

std::set_intersection 应该与此一起使用 Point class

struct Point
{
  int x, y;
  Point(void) : x(0), y(0) {}
  Point(const int &x, const int &y) : x(x), y(y) {}
 ~Point(void) {}
  Point& operator=(const Point &P) { x=P.x; y=P.y; return *this; }
  bool operator==(const Point &P) const { return ((x == P.x) && (y == P.y)); }
  bool operator<(const Point &P) const { return ((x == P.x) ? (y < P.y) : (x < P.x)); }
};

但您可以将 myset_intersection 实现为:

using Const_Iterator = set<Point>::iterator;
template<typename Iterator> Iterator myset_intersection(Const_Iterator first1, Const_Iterator last1, Const_Iterator first2, Const_Iterator last2, Iterator output)
{
  while ((first1 != last1) && (first2 != last2))
  {
    if ((*first1) == (*first2))
    {
      (*output) = (*first1); ++output; ++first1; ++first2;
    }
    else
    {
      if ((*first1) < (*first2)) ++first1;
      else ++first2;
    }
  }
  return output;
}