使用 std::sort 对包含两个数据成员的对象向量进行排序

Posted

技术标签:

【中文标题】使用 std::sort 对包含两个数据成员的对象向量进行排序【英文标题】:Sorting a vector of objects containing two data members using std::sort 【发布时间】:2016-03-15 17:47:59 【问题描述】:

我正在尝试将文件中的数据存储到对象向量中,然后对数据成员进行排序,但出现错误“无法确定要使用哪个重载函数“排序”实例”。我尝试过使用带有排序的 lambda,并且还认为这可能是我创建比较函数的方式(是 a.hour > b.hour 还是应该使用 a.getHour() 和 b.getHour()?)我实际上想按小时和分钟对向量进行排序,但首先仅在数小时内对其进行测试似乎不起作用。这就是我目前所拥有的

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
using namespace std;

class time 
    int hour;
    int minute;
public:
    time(int h, int m) 
        hour = h;
        minute = m;
    
    int getHour()  return hour; 
    int getMinute()  return minute; 
;

class Times 
    vector<time> t;
public:
    Times(string fileName) 
        //
    

    void parse(ifstream& file) 
        //
        sort.(t.begin(), t.end(), lowerThan);
        //sort.(t.begin(), t.end(), [] (time& a, time& b)  return a.hour < b.hour; )
    

    void display() 
        for (size_t i = 0; i < t.size(); i++) 
            cout << t[i].getHour() << ":" << t[i].getMinute() << endl;
        
    

    static bool lowerThan(time& a, time& b)  return a.getHour() < b.getHour(); 
;

int main() 
    Times times("File.txt");
    times.display();

    system("pause");
    return 0;

【问题讨论】:

第一个you should not use using namespace std;。其次,您似乎有错字。你有sort.(... 而不是sort(... 避免使用using namespace std,当您将std 中使用的名称用作time 时更是如此。 嗨,我在好几个地方都看到过这个,但是为什么要避免使用命名空间 std; ? @FirstStep 查看我评论中的链接 顺便说一句,即使没有using namespace std;,你的类time似乎与(C)函数time冲突,所以使用你自己的命名空间,或者重命名你的类time 【参考方案1】:

您的代码中有几个问题。

should not use using namespace std; 避免名字冲突。

此外,不幸的是,您的 time(小写)类与另一个 time 标准标识符冲突。只需使用Uppercase 命名类的约定。

此外,您可能希望将Time::getHour()Time::getMinute() 方法标记为const,因为它们不会修改Time 对象的内部状态。

sort 调用还有一个错字,因为sort 后面有一个点。

而且,在 C++11/14 中,我建议您使用 基于范围的 for 循环,而不是使用带有整数索引的显式 for

考虑到这些方面,我对您的代码进行了一些重构,it now works 使用了lowerThan() 静态方法和 lambda。随意学习。

#include <algorithm>
#include <iostream>
#include <vector>

class Time 
    int hour;
    int minute;
public:
    Time(int h, int m) : hour(h), minute(m) 
    

    int getHour() const  return hour; 
    int getMinute() const  return minute; 
;

class Times 
    std::vector<Time> t;

    static bool lowerThan(const Time& a, const Time& b)  
        return a.getHour() < b.getHour(); 
    

public:
    Times() 
        // Test data
        t.push_back(Time10, 10);
        t.push_back(Time9, 20);
        t.push_back(Time8, 30);

        //std::sort(t.begin(), t.end(), lowerThan);

        std::sort(t.begin(), t.end(), [] (const Time& a, const Time& b)  
            return a.getHour() < b.getHour(); 
        );
    

    void display() 
        for (const auto& x : t) 
            std::cout << x.getHour() << ":" << x.getMinute() << '\n';
        
    
;

int main() 
    Times times;
    times.display();


还请注意,如果您定义了自定义 operator&lt; 重载以对 Time 类的实例进行排序,则可以简单地调用 std::sort() 而无需任何自定义比较器,并且您的自定义实现 operator&lt; is automatically picked up by the compiler:

class Time 
...
    friend bool operator<(const Time& a, const Time& b) 
        return a.getHour() < b.getHour();
        // ... or a more complete comparison, including minutes.
       
;

编辑

正如@DieterLücking 在评论中所建议的,您可以使用std::tie() 来实现operator&lt; (live here on Ideone):

#include <tuple>  // for std::tie

class Time 
    ...
public:

friend bool operator<(const Time& a, const Time& b) 
    return std::tie(a.hour, a.minute) < std::tie(b.hour, b.minute);
   

;

【讨论】:

用于排序:std::tie(a.hour, a.minute) &lt; std::tie(b.hour, b.minute);std::make_tuple(a.getHour(), a.getMinute()) &lt; std::make_tuple(b.getHour(), b.getMinute()); 如果操作员不是朋友

以上是关于使用 std::sort 对包含两个数据成员的对象向量进行排序的主要内容,如果未能解决你的问题,请参考以下文章

使用 std::sort() 对对象向量进行排序

对多个数据成员进行排序[重复]

std::sort 对包含 Objects* 指针的 Objects 向量进行排序

sort中的比较函数compare

C++中得sort函数的比较函数(第三个参数)为什么要声明为static

如何使用单独类的属性对向量进行 std::sort [关闭]