c++STL标准库排序函数std::sort使用

2023-11-17

Qt系列文章目录

前言

C++ sort()排序函数
C++ STL 标准库中的 sort() 函数,本质就是一个模板函数。正如表 1 中描述的,该函数专门用来对容器或普通数组中指定范围内的元素进行排序,排序规则默认以元素值的大小做升序排序,除此之外我们也可以选择标准库提供的其它排序规则(比如std::greater降序排序规则),甚至还可以自定义排序规则。
sort() 函数是基于快速排序实现的,有关快速排序的具体实现过程,感兴趣的读者可阅读《快速排序(QSort,快排)算法》一文。

需要注意的是,sort() 函数受到底层实现方式的限制,它仅适用于普通数组和部分类型的容器。换句话说,只有普通数组和具备以下条件的容器,才能使用 sort() 函数:
容器支持的迭代器类型必须为随机访问迭代器。这意味着,sort() 只对 array、vector、deque 这 3 个容器提供支持。
如果对容器中指定区域的元素做默认升序排序,则元素类型必须支持<小于运算符;同样,如果选用标准库提供的其它排序规则,元素类型也必须支持该规则底层实现所用的比较运算符;
sort() 函数在实现排序时,需要交换容器中元素的存储位置。这种情况下,如果容器中存储的是自定义的类对象,则该类的内部必须提供移动构造函数和移动赋值运算符。

另外还需要注意的一点是,对于指定区域内值相等的元素,sort() 函数无法保证它们的相对位置不发生改变。例如,有如下一组数据:

bool MainFramework::sortStrips(const QString &a, const QString &b)
{
    QStringList aSplit = a.split('_');
    QStringList bSplit = b.split('_');

    int aFirstPart = aSplit[0].toInt();
    int bFirstPart = bSplit[0].toInt();

    if (aFirstPart == bFirstPart) {
        int aSecondPart = aSplit[5].toInt();
        int bSecondPart = bSplit[5].toInt();
        return aSecondPart > bSecondPart;
    } else {
        return aFirstPart < bFirstPart;
    }
}

void MainFramework::groupStrips()
{
    for(const QString& fileName : m_colorCAllFiles)
    {
        if(fileName.contains("_04_")) {
            m_colorCfiles04.append(fileName);
        } else if(fileName.contains("_02_")) {
            m_colorCfiles02.append(fileName);
        } else if(fileName.contains("_05_")) {
            m_colorCfiles05.append(fileName);
        }
    }

    std::sort(m_colorCfiles04.begin(), m_colorCfiles04.end(), sortStrips);
    std::sort(m_colorCfiles02.begin(), m_colorCfiles02.end(), sortStrips);
    std::sort(m_colorCfiles05.begin(), m_colorCfiles05.end(), sortStrips);

}

在使用c++STL标准库排序函数std::sort编译器报错:1.E:\work\ImageManageSys\MainFramework.cpp:586: error: C3867: “MainFramework::sortStrips”: 非标准语法;请使用 “&” 来创建指向成员的指针
2.E:\work\ImageManageSys\MainFramework.cpp:586: error: C2672: “std::sort”: 未找到匹配的重载函数
3.E:\work\ImageManageSys\MainFramework.cpp:586: error: C2780: “void std::sort(const _RanIt,const _RanIt)”: 应输入 2 个参数,却提供了 3 个
MainFramework.cpp(586): error C2780: “void std::sort(const _RanIt,const _RanIt)”: 应输入 2 个参数,却提供了 3 个
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\algorithm(7403): note: 参见“std::sort”的声明

在这里插入图片描述

一、错误原因

这个错误是因为在使用std::sort()时,你传递了一个成员函数指针,而非普通函数指针。为了解决这个问题,你可以使用C++11的lambda表达式作为比较器。以下是修改后的groupStrips()方法:

二、修改后的代码


bool MainFramework::sortStrips(const QString &a, const QString &b)
{
    QStringList aSplit = a.split('_');
    QStringList bSplit = b.split('_');

    int aFirstPart = aSplit[0].toInt();
    int bFirstPart = bSplit[0].toInt();

    if (aFirstPart == bFirstPart) {
        int aSecondPart = aSplit[5].toInt();
        int bSecondPart = bSplit[5].toInt();
        return aSecondPart > bSecondPart;
    } else {
        return aFirstPart < bFirstPart;
    }
}

void MainFramework::groupStrips()
{
    for(const QString& fileName : m_colorCAllFiles)
    {
        if(fileName.contains("_04_")) {
            m_colorCfiles04.append(fileName);
        } else if(fileName.contains("_02_")) {
            m_colorCfiles02.append(fileName);
        } else if(fileName.contains("_05_")) {
            m_colorCfiles05.append(fileName);
        }
    }

    auto sortStripsLambda = [this](const QString &a, const QString &b) {
        return this->sortStrips(a, b);
    };

    std::sort(m_colorCfiles04.begin(), m_colorCfiles04.end(), sortStripsLambda);
    std::sort(m_colorCfiles02.begin(), m_colorCfiles02.end(), sortStripsLambda);
    std::sort(m_colorCfiles05.begin(), m_colorCfiles05.end(), sortStripsLambda);
}

我们在groupStrips()方法内定义了一个名为sortStripsLambda的lambda表达式,这个表达式将调用sortStrips()成员函数。然后,我们将sortStripsLambda作为比较器传递给std::sort()函数。现在这段代码应该能够正常编译并运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++STL标准库排序函数std::sort使用 的相关文章

  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • std::cout 和 std::wcout 有什么区别?

    在c 中 有什么区别std cout and std wcout 它们都控制流缓冲区的输出或将内容打印到控制台 或者它们只是相似吗 它们作用于不同的字符类型 std cout uses char作为字符类型 std wcout uses w
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 如何在 C# 中从 UNIX 纪元时间转换并考虑夏令时?

    我有一个从 unix 纪元时间转换为 NET DateTime 值的函数 public static DateTime FromUnixEpochTime double unixTime DateTime d new DateTime 19
  • 推导指南中的引用和值之间的差异

    考虑类型A template
  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • C++中的类查找结构体数组

    我正在尝试创建一个结构数组 它将输入字符串链接到类 如下所示 struct string command CommandPath cPath cPathLookup set an alarm AlarmCommandPath send an
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • 使用 C 语言使用 strftime() 获取缩写时区

    我看过this https stackoverflow com questions 34408909 how to get abbreviated timezone and this https stackoverflow com ques
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐

  • 集成学习与深度学习 加载模型方法

    1 集成学习 import joblib joblib load model pkl 2 深度学习 用torch自带的load import torch data torch load model pkl error pickle Unpi
  • JDK8 字节码操作

    java字节码技术 1 BCEL 基于汇编 2 ASM 轻量级 3 javassist 性能比发射高 比asm低 使用简单 4 cglib 基于ASM 应用场景 1 动态修改class文件 对类进行增删改 2 aop技术 3 lombok
  • 树、森林与二叉树相互转化

    1 树转换为二叉树 由于二叉树是有序的 为了避免混淆 对于无序树 我们约定树中的每个结点的孩子结点按从左到右的顺序进行编号 将树转换成二叉树的步骤是 1 加线 就是在所有兄弟结点之间加一条连线 2 抹线 就是对树中的每个结点 只保留他与第一
  • 《数字图像处理》学习总结及感悟:第二章数字图像基础(5)数学工具

    前往老猿Python博文目录 https blog csdn net LaoYuanPython 一 引言 本系列文章记录老猿自学冈萨雷斯 数字图像处理 的感悟和总结 不过估计更新会比较慢 白天要工作 都是晚上抽空学习 学习完一章再回头总结
  • 不小心删除了网络适配器中的无线网卡驱动?

    昨天电脑蓝屏了几次 查了下问题 有人说把win10的网卡重新安装下就好了 结果 我直接把网络适配器的无线网卡驱动给卸载了 就是这个样子 点击卸载后 网络适配器下面没有无线网卡的驱动 电脑也连不了网 还没有网线 驱动精灵就是垃圾 它没有适配我
  • 校招高频必背考点

    2 操作系统 2 1 基础 进程与线程的本质区别 以及各自的使用场景 进程是操作系统资源分配的基本单位 线程是操作系统调度的最小单位 一个进程可以中可以有多个线程 线程依赖于进程存在 进程状态 阻塞 就绪 运行 进程调度算法的特点以及使用场
  • 【分析笔记】全志 T507 PF4 引脚无法被正常设置为中断模式的问题分析

    相关信息 硬件平台 全志T507 系统版本 Android 10 Linux 4 9 170 问题描述 PF4 无法通过标准接口设置为中断模式 而 PF1 PF2 PF3 PF5 正常可用 分析过程 一开始以为是引脚被其它驱动占用引起 或者
  • vue路由配置

    import Vue from vue import Router from vue router Vue use Router Note 路由配置项 hidden true 当设置 true 的时候该路由不会再侧边栏出现 如401 log
  • flutter项目中 advance_image_picker 组件使用

    一 说明 Advance image picker 是flutter 插件 用于从Android 和 ios 图像库中选择多张图片 使用相机拍摄新照片 并对其进行编辑 下图为最终效果 这里有个bug 在连续多测按 旋转摄像头时 程序会出现卡
  • 关于TypeError:xxx() missing 1 required positional argument: ‘S‘问题处理意见

    关于TypeError xxx missing 1 required positional argument S 问题处理意见 关于调用python模块的方法总结 在调用自己保存的模块 py文件时 导入后就直接进行 文件名 函数进行调用 会
  • 查询手机所在地理位置的简单方法

    有时候坐在长途汽车或火车上 想知道现在到什么地方了 可以通过手机来简单定位 对于没有GPS功能的手机 要想知道当前所在地理位置 可以通过基站定位 具体有以下几种方法 1 直接查看基站编号 使用某些手机的工程模式 或者利用专门的软件 比如S6
  • Java中new Date().getTime()时间戳问题

    1 getTime 返回值 Java和JavaScript都支持时间类型Date 他们的getTime 方法返回的是毫秒数 默认返回的是13位数字 单位是毫秒 2 注意事项 Returns the number of millisecond
  • 无线 连接公司服务器,客户端无线连接服务器

    客户端无线连接服务器 内容精选 换一换 您可以在弹性负载均衡服务中创建一个负载均衡器 该负载均衡器会接收来自客户端的请求 并将请求转发到一个或多个可用区的后端服务器中进行处理 请求的流量分发与负载均衡器配置的分配策略类型相关 共享型和独享型
  • apache kafka_Apache Kafka简介

    apache kafka During the last years technologies for building real time data pipelines and event streaming apps have emer
  • 红队隧道应用篇之DNS协议传输(九)

    简介 DNS隧道是一种相对隐蔽的隧道 通过将其他协议封装到DNS协议中来进行传输通信 因为DNS协议是网络中的基础协议且必不可少 所以大部分防火墙和入侵检测设备是不会对DNS流量进行拦截 这就给DNS作为隐蔽通信提供了有力条件 从而可以利用
  • 程序员面试题精选100题(30)-赋值运算符重载函数[C/C++/C#]

    程序员面试题精选100题 30 赋值运算符重载函数 C C C 问题 给出如下CMyString的声明 要求为该类型添加赋值运算符函数 class CMyString public CMyString char pData NULL CMy
  • 蓝桥杯题库 历届试题部分(C++、Java)代码实现(46-60)

    文章目录 五 历届试题 PREV 46 填字母游戏 PREV 47 区间移位 PREV 48 数组操作 PREV 49 发现环 PREV 50 对局匹配 PREV 51 观光铁路 PREV 52 小数第n位 PREV 53 分考场 PREV
  • 使用 ChatGPT 总是出现「Something went wrong」解决方案

    1 前言 最近使用 ChatGPT 总是出现 Something went wrong If this issue persists please contact us through our help center at help ope
  • ARM汇编快速入门

    本文主要分享如何快速上手ARM汇编开发的经验 汇编开发中常见的Bug以及Debug方法 用的Convolution Dephtwise算子的汇编实现相对于C 版本的加速效果三方面内容 前言 神经网络模型能够在移动端实现快速推理离不开高性能算
  • c++STL标准库排序函数std::sort使用

    Qt系列文章目录 文章目录 Qt系列文章目录 前言 一 错误原因 二 修改后的代码 前言 C sort 排序函数 C STL 标准库中的 sort 函数 本质就是一个模板函数 正如表 1 中描述的 该函数专门用来对容器或普通数组中指定范围内