【问题标题】:using C++ std::sort with lambda comparator使用带有 lambda 比较器的 C++ std::sort
【发布时间】:2016-09-04 09:53:01
【问题描述】:

我正在尝试使用 std::sort 对对象数组进行排序 -

sort(convexHull.getSet(), convexHull.getSet()+convexHull.size(),
     [](const Point & a, const Point & b) -> bool
     {             if (a.getX() < b.getX())
         return true;
     else if (a.getX() == b.getX())
         return a.getY() < b.getY();
     else
         return false;; }
);

convexHull.getSet() 返回一个指向数组开头的指针。

正如here 解释的那样。

但是我的编译器(Clion)出现了一个很长的错误,关于我的赋值运算符 -

#include <cmath>
#include <string>

using namespace std;

class Point
{

private:
    int _x;
    int _y;
    double _arg;

    void setArg()
    {        
       if(sqrt(_x*_x + _y*_y) == 0)
            _arg = 5;
        else
            _arg = _y / sqrt(_x*_x + _y*_y);
    }

public:
    Point () : Point(0, 0) {}

Point (const int x, const int y) : _x(x), _y(y)
{
    setArg();
}

int getX () const
{ return _x; }

int getY () const
{ return _y; }


    ~Point () {}

    Point& operator= (const Point &rval);
};

(其中 setArg 只是从正 x 轴计算点角度)。

我已经使用此代码测试了运算符 -

Point p(5,5);
Point t(3,3);
t=p;
t.setXY(7,7);

它似乎工作正常。

篇幅太长,我只发一部分——

   In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/algorithm:62:0,
                 from /cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:7:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h: In instantiation of 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = const Point*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const Point&, const Point&)> >]':
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:1880:25:   required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = const Point*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const Point&, const Point&)> >]'
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:1966:31:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = const Point*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(const Point&, const Point&)> >]'
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:4729:18:   required from 'void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = const Point*; _Compare = main()::<lambda(const Point&, const Point&)>]'
/cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:75:5:   required from here
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h:1847:17: error: passing 'const Point' as 'this' argument discards qualifiers [-fpermissive]
        *__first = _GLIBCXX_MOVE(__val);
                 ^
In file included from /cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/PointSet.h:9:0,
                 from /cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:4:
/cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/Point.h:45:12: note:   in call to 'Point& Point::operator=(const Point&)'

这也可能是相关的 -

/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/predefined_ops.h:123:46: note: candidate: bool (*)(Point&, Point&) <conversion>
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/predefined_ops.h:123:46: note:   conversion of argument 3 would be ill-formed:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/predefined_ops.h:123:46: error: binding 'const Point' to reference of type 'Point&' discards qualifiers
/cygdrive/c/Users/o/Desktop/CPP/ex1/cppex1/ex1/ConvexHull.cpp:68:38: note: candidate: main()::<lambda(Point&, Point&)> <near match>
          [](Point & a, Point & b) -> bool

【问题讨论】:

  • Point&amp; Point::operator= (const Point &amp;rval) 可能会解决这个问题。
  • @πάνταῥεῖ 这不是关于重载的问题,而是关于使用排序的问题。我的操作员工作得很好。
  • @n.m. “关于我的赋值运算符”
  • 您的编译器错误表明您拥有Point&amp; operator= (Point &amp;rval);,但您声称拥有Point&amp; operator= (const Point &amp;rval);。检查您的来源是否是最新的。
  • 错误信息现在不同了。此外,现在你的编译器抱怨[](Point &amp; a, Point &amp; b) -&gt; bool,而你声称你有[](const Point &amp; a, const Point &amp; b) -&gt; bool。除非您提供minimal reproducible example,否则无法弄清楚发生了什么。

标签: c++ sorting c++11 lambda


【解决方案1】:

显然问题不在于比较,而在于您传递给std::sort 的内容。声明是什么

convexHull.getSet()

?

例如,如果返回 const Point *,那么您有一个 const 正确性问题,因为 std::sort 需要能够写入以重新排列元素。

【讨论】:

  • 完全同意您的分析(根据 OP 的说法,一切正常:ideone.com/J6TDhU)!但这不是对不完整问题的评论而不是明确的答案吗?
  • 这似乎是问题所在,我更改了 getSet() 的签名以返回一个非常量指针,现在我的代码可以编译了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 2011-08-14
  • 2019-11-04
  • 1970-01-01
相关资源
最近更新 更多