文章目录
1 代码实现及 示例
要按照从左到右、从上到下的顺序对坐标点进行排序,你可以定义一个比较函数,然后使用 std::sort 函数进行排序。
1.1 比较函数
std::sort 函数默认只能对基本数据类型或者自定义的比较函数进行排序,而 Point2f 并不直接支持比较操作。因此,我们需要提供一个自定义的比较函数给 std::sort 使用。
bool comparePoints(const cv::Point2f& p1, const cv::Point2f& p2)
{
// 先按照 y 值进行排序
if (p1.y != p2.y) {
return p1.y < p2.y;
}
// 如果 y 值相等,则按照 x 值进行排序
return p1.x < p2.x;
}
1.2 使用 sort进行排序,
//// 对坐标点进行排序
std::sort(Center.begin(), Center.end(),comparePoints);
1.3 完整调用代码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace cv;
using namespace std;
bool comparePoints(const cv::Point2f& p1, const cv::Point2f& p2) {
if (p1.y != p2.y) {
return p1.y < p2.y;
}
return p1.x < p2.x;
}
int main() {
// 假设 Center 是你存放坐标点的 vector
vector<Point2f> Center = {
Point2f(100, 50),
Point2f(90, 60),
Point2f(130, 55),
Point2f(200, 30),
Point2f(180, 40),
Point2f(160, 70),
// 继续添加其他坐标点...
};
// 对坐标点进行排序
sort(Center.begin(), Center.end(), comparePoints);
// 输出排序后的坐标点
for (const auto& point : Center) {
cout << "(" << point.x << ", " << point.y << ")" << endl;
}
return 0;
}
1.4 lambda 表达式代替比较函数
//对坐标点进行排序
sort(Center.begin(), Center.end(), [](const cv::Point2f& p1, const cv::Point2f& p2) {
if (p1.y != p2.y) {
return p1.y < p2.y;
}
return p1.x < p2.x;
});
2 可能出现的错误 C3867,C2672
bool comparePoints(const cv::Point2f& p1, const cv::Point2f& p2)
{
// 先按照 y 值进行排序
if (p1.y != p2.y) {
return p1.y < p2.y;
}
// 如果 y 值相等,则按照 x 值进行排序
return p1.x < p2.x;
}
//// 对坐标点进行排序
std::sort(Center.begin(), Center.end(),comparePoints);
报错

严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 C3867 “getLine::comparePoints”: 非标准语法;请使用 "&" 来创建指向成员的指针
严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 C2672 “std::sort”: 未找到匹配的重载函数
2.1 解决方法1——失败
在C++中,std::sort 函数要求传递的比较函数必须是函数指针,在使用方法一时,编译器可能会将 comparePoints 函数视为成员函数,而不是函数指针,从而导致报错。
为了解决方法一中的问题,可以使用函数指针来传递 comparePoints 函数。这可以通过在函数名前面加上 & 来实现。修正后的代码如下所示:
// 对坐标点进行排序
sort(Center.begin(), Center.end(), &comparePoints);
仍然报错“严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 C2276 “&”: 绑定成员函数表达式上的非法操作
2.2 解决方法2——成功
C++中的成员函数指针与普通函数指针有所不同。成员函数指针必须指定对象,因为它们需要一个对象来调用。所以,在使用成员函数指针时,需要同时传递对象。
如果你希望使用方法一中的比较函数 comparePoints,需要将其定义为静态成员函数,或者将其放置在全局作用域中。这样,它就可以像普通函数一样使用,并且可以传递给 std::sort。
将比较函数 comparePoints在头文件中的 声明去掉,文解决

2.3 解决方法3——成功
lambda 表达式代替比较函数 comparePoints;
Lambda 表达式是可以隐式地转换为函数指针的,因此可以正常工作。
//对坐标点进行排序
sort(Center.begin(), Center.end(), [](const cv::Point2f& p1, const cv::Point2f& p2) {
if (p1.y != p2.y) {
return p1.y < p2.y;
}
return p1.x < p2.x;
});
2.4 解决方法4——成功
如果想使用非静态成员函数,你需要使用成员函数指针来传递。
这可能需要一些额外的工作。以下是一个示例代码,演示了如何使用成员函数指针来进行排序:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace cv;
using namespace std;
class MyClass {
public:
bool comparePoints(const Point2f& p1, const Point2f& p2) {
if (p1.y != p2.y) {
return p1.y < p2.y;
}
return p1.x < p2.x;
}
void sortPoints(vector<Point2f>& points) {
sort(points.begin(), points.end(), [this](const Point2f& p1, const Point2f& p2) {
return comparePoints(p1, p2);
});
}
};
int main() {
MyClass obj;
// 假设 Center 是你存放坐标点的 vector
vector<Point2f> Center = {
Point2f(100, 50),
Point2f(90, 60),
Point2f(130, 55),
Point2f(200, 30),
Point2f(180, 40),
Point2f(160, 70),
// 继续添加其他坐标点...
};
// 使用成员函数指针对坐标点进行排序
obj.sortPoints(Center);
// 输出排序后的坐标点
for (const auto& point : Center) {
cout << "(" << point.x << ", " << point.y << ")" << endl;
}
return 0;
}
在这个示例中,我们创建了一个名为 MyClass 的类,其中包含了一个非静态成员函数 comparePoints,用于比较坐标点。然后,我们在 MyClass 中定义了一个新的成员函数 sortPoints,该函数接受一个 vector<Point2f> 类型的参数,并使用 lambda 表达式来调用 comparePoints 函数进行排序。最后,我们在 main 函数中创建了 MyClass 的实例,并调用 sortPoints 函数来对坐标点进行排序。
浙公网安备 33010602011771号