C++11 sort using function objects

来源:互联网 发布:网络成瘾的影响 编辑:程序博客网 时间:2024/05/17 22:10

如果你用C++编码, 需要对容器内的元素进行排序, 这个容器提供任意访问的迭代器, 比如std::vector, 那么简单快捷的方法是使用里的std::sort 函数.

Basic sorting
std::sort 函数需要两个参数, 这两个参数分别指向你要排序的序列容器的开始(initial)和终点(final). 这个序列容易内除final指向的那个元素外 所有元素都会被排序.
下面是一个简单的排序例子:

#include <algorithm>#include <vector>const int array[] {10, 20, 5, 15, 0};std::vector<int> vec(array, array + 5);std::sort(vec.begin(), vec.end());

输出:
0 5 10 15 20

More complex sorting
在某些时候, 根据数值升序排序已经足够解决问题了, 但是当我们需要按某个特定的参数进行排序, 或者降序排列时, 就需要一些其他的东西了.
对于这种需求, std::sort 需要引入第三个参数: 比较函数. 这个比较函数有两个参数, 分别是序列容器的两个元素, 返回值可以隐式地转为bool. 如果第一个参数应该排在第二个参数前面, 则返回true.

例:

#include <algorithm>#include <vector>bool DescOrderInt(int a, int b);...const int array[] = {10, 20, 5, 15, 0};std::vector<int> vec(array, array + 5);std::sort(vec.begin(), vec.end(), DescOrderInt);

DescOrderInt的实现:

bool DescOrderInt(int a, int b){    return a > b;}

输出:
20 15 10 5 0

C++11 sort using function objects
网上很多例子说, 为了排列元素, 可以使用std::binary_function 定义比较函数, 但不幸的是, std::binary_function 在C++11 中已经被标为 “将被弃用的”, 在C++17中会被完全移除, 所以写新的C++代码时, 最好不要用这个.

我们可以使用C++11中引入的std::function 来定义这个函数指针.
例:

#include <algorithm>#include <function>#include <vector>struct StrDescOrderInt{    bool operator()(int a, int b) const    {        return a > b;    }};...const int array[] = {10, 20, 5, 15, 0};std::vector<int> vec(array, array + 5);std::function<bool(int, int)> sorter = StrDescOrderInt();std::sort(vec.begin(), vec.end(), sorter);

输出:
20 15 10 5 0

A real-life example: providing multiple sorting options
我们假设有一队足球运动员, 我们想让用户按他们自己的意愿去排列这些运动员. 有一个图表的UI, 上面有几个按钮, 每个按钮对应不用的排序规则.

Plaer 类的代码:

// -- Player.h --#include <string>class Player{   public:    Player(const char * name, int caps, int goals);    const std::string & GetName() const;    int GetCaps() const;    int GetGoals() const; private:    std::string mName;    int mCaps;    int mGoals;};  

现在我们新写一个类或结构体来列出所有的比较函数. 比较函数是一个结构体并实现操作符(), 操作符() 带有两个参数, 分别为两个指向Player的指针, 返回bool值.

class Player;struct PlayerSorting{    // name    struct SortPlayerByNameAsc (bool operator()(Player* p1, Player* p2) const;);    struct SortPlayerByNameDes (bool operator()(Player* p1, Player* p2) const;);    // caps    struct SortPlayerByCapsAsc (bool operator()(Player* p1, Player* p2) const;);    struct SortPlayerByCapsDes (bool operator()(Player* p1, Player* p2) const;);    // goals    struct SortPlayerByGoalsAsc (bool operator()(Player* p1, Player* p2) const;);    struct SortPlayerByGoalsDes (bool operator()(Player* p1, Player* p2) const;);}

然后, 在调用它的地方, 我们可以先把所有的std::function 存在一个std::vector 里, 使用的时候, 用索引访问vector的元素.

std::vector< std::function<bool(Player *, Player *)> > sorters;sorters.push_back(PlayerSorting::SortPlayerByNameAsc());sorters.push_back(PlayerSorting::SortPlayerByCapsAsc());sorters.push_back(PlayerSorting::SortPlayerByGoalsAsc());sorters.push_back(PlayerSorting::SortPlayerByNameDes());sorters.push_back(PlayerSorting::SortPlayerByCapsDes());sorters.push_back(PlayerSorting::SortPlayerByGoalsDes());

例如, 根据得分降序排列:

std::vector<Player *> players;// ...init players...std::sort(players.begin(), players.end(), sorters[5]);

输出:

NAME                     CAPS  GOALS Lionel Messi             21    20    David Villa              13    16    Asamoah Gyan             22    15    Arjen Robben             11    12    Mesut Oezil              19    10    Diego Forlan             20    10    Andres Iniesta           15    9     Wesley Sneijder          24    6     Xavi                     17    5     Bastian Schweinsteiger   23    4

假如需要实现一种新的排序方式, 我们只需要在PlayerSorting类中添加一个新的仿函数即可.

原文地址: http://blog.davidecoppola.com/2015/01/cpp11-sort-using-function-objects/

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 口臭想让它变得不臭怎么办 来单位干了几天不满意想离职怎么办 药流吃药期间吃什么吐什么怎么办 养狗家里味道大怎么办养花有用吗 第一天上班站的脚疼怎么办 入职没有人事所需要的证书怎么办 入职第一天后不想去了怎么办 警察在执法过程中殴打群众怎么办 肾结石打了3天针痛得厉害怎么办 征兵体检过了到部队退兵怎么办 圆通快递要求退回结果被签收怎么办 新生儿蛋蛋淹了破皮了怎么办 要是和同学玩的时候打到睾丸怎么办 睾丸撞了一下里面碎了怎么办 睾丸被蚊子咬了挠坏流水疼怎么办 沐浴乳大量的灌注到尿道里怎么办 当电脑显示有文件损害时怎么办? 电脑上的压缩包手机上打不开怎么办 第五人格多酷账号退出了怎么办 更新显卡驱动时屏幕关闭了怎么办 不知道杯孕做了两次C丁怎么办 小说签约后更不到要求的字数怎么办 电脑中了感染病毒杀不干净怎么办 电脑下载的软件有病毒了怎么办 电脑强制关机后开不了机怎么办 受刺激后出现精神异常该怎么办 当屏幕出现暂时无法移动时怎么办 英雄联盟欧服连接不上服务器怎么办 试客联盟认证手机号成空号了怎么办 汽车脚垫不贴合翘起来了怎么办 版权保护迅雷下载不了的资源怎么办 30岁在外地城市找不到工作怎么办 新买的苹果爱拍充不进去电是怎么办 绝地求生东南亚服匹配不到人怎么办 电脑卡住了怎么办鼠标也点不动 幽灵行动荒野没有主线任务了怎么办 拼多多购买的东西下架了怎么办 电脑版的荒野行动玩的时候卡怎么办 欧洲卡车模拟2气压过低怎么办 word页眉和正文有段距离怎么办 酷派大神x7卡在开机界面怎么办