使用myclass :: operator [](int i)对std :: list <myclass *>进行排序

时间:2016-05-13 22:09:37

标签: c++ list std

我想根据参数对列表std :: list进行排序。例如:

class myclass
{
    string name, surname;
public:
    myclass() {}
    ~myclass() {}
    string operator[](int i)
    {
        switch (i)
        {
        case 1: return name;
        case 2: return surname;
        }
    }
};

template <typename T>
struct compare
{
    int num;
    indirect_compare() {}
    indirect_compare(int i) : num(i) {}
    ~indirect_compare() {}
    bool operator()(T * lhs, T * rhs) { return (*lhs)[num] < (*rhs)[num]; }
};

list<myclass*> lst;  
int specified_by_user;  
cin >> specified_by_user;  

//later

lst.sort(compare<myclass>(specified_by_user));

它适用于我,但我不确定它是否正确。当我在构造函数中添加一些消息并在结构比较中添加析构函数时,我看到构造函数只调用了一次,但析构函数被调用了9次,我不知道它为什么会发生。我试图调试这个程序来检查它,但我找不到原因。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我会尝试将开关从operator []移动到比较函数对象(甚至可以使用lambda)。这将允许您比较不同类型的属性。 (例如,如果您添加成员int age;

此外,我会有一个事物列表,而不是一个指向事物的指针列表。你可能会得到1个构造函数和多个删除问题,因为你对指针不够谨慎。

这样的事情:

struct myclass
{
  string name;
  string surname;
};

template <typename T>
struct compare
{
  int num;
  compare() {}
  compare(int i) : num(i) {}
  ~compare() {}
  bool operator()(const T & lhs, const T & rhs) {
    switch(num)
    {
       case 1: return lhs->name < rhs->name;
       case 2: return lhs->surname < rhs->surname;
       default: throw std::logic_error();
    }
  }
};

list<myclass> lst;

答案 1 :(得分:0)

你的代码看起来很好。你的解决方案有点不寻常,但如果它适合你,那就去吧!本着Mircea Baja的精神,我想向您展示一个解决您问题的替代方案,仅仅是为了获得灵感:

if (specified_by_user) // sort by name
    lst.sort(auto [](auto const & a, auto const & b){ return a.name < b.name; });
else // sort by surname
    lst.sort(auto [](auto const & a, auto const & b){ return a.surname < b.surname; });

首先,我们决定通过哪个字段来排序您的类和客户端代码。其次,我们不是定义比较器结构,而是将lambdas传递给lst.sort(),它可以非常简洁地定义,在函数调用本身内联。

这意味着字段名称和姓氏是公共的(因此lambdas可以访问它们)。如果您想将它们保密,您可以将吸气剂添加到您的班级中:

string const & get_name() const { return name; }

并稍微改变lambda:

auto [](auto const & a, auto const & b){ return a.get_name() < b.get_name(); }