使用std :: tie进行排序

时间:2014-07-13 13:27:31

标签: c++ windows visual-studio-2010 std

我使用std::tie作为仿函数来对结构列表进行排序。但我不明白为什么它不起作用。所以这是我的代码:

#include <tuple>


class Point
{
 public:
    double x(void) const;
    double y(void) const;
    double z(void) const;

    double& x(void);
    double& y(void);
    double& z(void);
};

struct Xitem
{
    int ID;
    Point eP;
};


  class X_Struct_Sorter
  {
  public:
       X_Struct_Sorter(){}
      bool operator()(const Xitem& a, const Xitem& b)
       {
            return std::tie(a.eP.x(),a.eP.y(),a.eP.z(),a.ID)
                     <std::tie(b.eP.x(),b.eP.y(),b.eP.z(),b.ID);
       }

  };

 QList<Xitem> X_Structure;
 ///The function I use to sort X_Structure.  
 void sortX_Structure()
 {
       X_Struct_Sorter s();
       qSort(X_Structure.begin(),X_Structure.end(),s);
 }

我使用排序器对Xitem的列表进行排序,我得到的只是eP.x()的排序。 eP.y()尚未排序。

问题:   这里的问题是使用后{1}}或std::sort()的Xitem列表的顺序与我预期的一样。我想要的是字典顺序(qSort)。所以我认为可能是操作员的仿函数问题。

更新数据: 这是我应用此功能后获得的数据。 语法是:

x()->y()->z()->ID

输入是:

    ID  | x() | y() | z()

输出结果为:

    0 | -38.8001 | 2.28723 | 0
   -1 | 1.26267 | 3.23 | 0
    1 | -38.1815 | 1.67529e-005 | 0
   -1 | -34.9763 | 0.334298 | 0
    2 | -34.2488 | 0.00119263 | 0
   -1 | 0.141234 | 0.839389 | 0
    3 | -38.1815 | 0.00364942 | 0
    -1 | 0.141234 | 0.839409 | 0
    4 | -38.1815 | 1.67529e-005 | 0
   -1 | -34.9763 | 0.334298 | 0
   5 | -38.1815 | 0.333395 | 0
  -1 | -38.1815 | 0.337506 | 0
  .....(sorry but the data is too long!)

我的期望:

     20 | -38.8001 | 2.36565 | 0
     17 | -38.8001 | 0.333395 | 0
     21 | -38.8001 | 3.18365 | 0
     26 | -38.8001 | 0.3343 | 0
     23 | -38.8001 | 0.3343 | 0
     0 | -38.8001 | 2.28723 | 0
    22 | -38.8001 | 3.18364 | 0
    -1 | -38.8001 | 3.64414 | 0
    12 | -38.1815 | 0.334007 | 0 

You can see here in the first line of data. The `y()` of first Xitem is 2.36565 > 0.333395 of second one. So, I got a trouble here.

就像你看到的那样,订单很糟糕。

1 个答案:

答案 0 :(得分:4)

std::tie需要 lvalues Point x()y()z()函数不会返回引用,因此它们会提供 rvalues 。一个简单的修复可能是为double& x()提供引用返回getter(例如Point),或者至少提供:

double ax = a.eP.x();
double ay = a.eP.y();
double az = a.eP.z();
double bx = b.eP.x();
double by = b.eP.y();
double bz = b.eP.z();

return std::tie(ax, ay, az, a.ID)
           < std::tie(bx, by, bz, b.ID);

例如,您可以在左值 rvalues here上阅读更多内容。

评论中jrok给出的另一种可能性是使用std::forward_as_tuple。但是,如果您在编辑后Point实施,则看起来没有必要。

另外,正如Qt&#39; documentation所述,您应该直接使用STL算法,Qt的功能无论如何都要转发它们:

  

历史上,Qt过去常常提供与许多STL算法函数直接等价的函数。从Qt 5.0开始,我们鼓励您直接使用STL中可用的实现;大多数Qt已被弃用(尽管它们仍可用于保留旧代码编译)。

您提供的代码适用于std::vectorstd::sort,请参阅Ideone上的演示。