使用std::tie进行排序
using std::tie for sorting
我使用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
s的列表进行排序,我得到的只是eP.x()
的排序。eP.y()
未排序
问题:这里的问题是使用std::sort()
或qSort
后Xitem列表的顺序不像我期望的那样。我这里想要的是字典顺序(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.
我的期望:
17 | -38.8001 | 0.333395 | 0
26 | -38.8001 | 0.3343 | 0
23 | -38.8001 | 0.3343 | 0
0 | -38.8001 | 2.28723 | 0
20 | -38.8001 | 2.36565 | 0
21 | -38.8001 | 3.18365 | 0
22 | -38.8001 | 3.18364 | 0
-1 | -38.8001 | 3.64414 | 0
12 | -38.1815 | 0.334007 | 0
就像你看到的,订单很糟糕。
std::tie
要求左值。Point
的x()
、y()
和z()
函数不返回引用,因此它们给出右值。一个简单的修复可能是为Point
提供引用返回getter(例如double& x()
),或者至少:
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);
你可以在这里阅读更多关于左值和右值的信息。
jrok在评论中给出的另一个可能性是使用std::forward_as_tuple
。然而,考虑到你的Point
实现后,你的编辑似乎没有必要。
同样,正如Qt的文档中所指出的,你应该直接使用STL算法,Qt的函数将调用转发给它们:
从历史上看,Qt提供的函数直接等价于许多STL算法函数。从Qt 5.0开始,我们鼓励您直接使用STL中提供的实现;大多数Qt已被弃用(尽管它们仍然可用以保持旧代码的编译)。
您提供的代码在std::vector
和std::sort
上正常工作,参见Ideone上的演示。
相关文章:
- 二叉排序树无法编译
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- 对字符串进行排序时,在c++中处理sort()
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 下面是排序算法O(n)吗
- std::sort()函数无法对向量的一部分进行排序
- shell排序中的交换和比较
- clang格式:禁用排序包含
- 显示错误输出的简单数组排序程序
- 为什么我的排序算法会更改数组值
- 使用std::tie进行排序
- c++11结合了std::tuple和std::tie来实现高效排序