【问题标题】:std::sort without functors没有仿函数的 std::sort
【发布时间】:2009-06-01 07:45:46
【问题描述】:

我有一个关于 std::sort 算法的问题。这是我的测试代码:

struct MyTest
{
    int m_first;
    int m_second;

    MyTest(int first = 0, int second = 0) : m_first(first), m_second(second)
    {
    }
};


int main(int argc,char *argv[])
{
    std::vector<MyTest> myVec;
    for(int i = 0; i < 10; ++i)
    {
        myVec.push_back(MyTest(i, i + 1));
    }


    //Sort the vector in descending order on m_first without using stand alone function or functors


    return 0;

}  

是否可以在不使用任何独立函数或仿函数的情况下对变量m_first 上的向量进行排序?另外,请注意我没有使用 boost。

【问题讨论】:

    标签: c++ stl sorting functor


    【解决方案1】:

    可以,只要要排序的范围内的值类型有一个operator &lt;,它定义了“严格弱排序”,也就是说,它可以用来正确比较两个MyTest实例。你可能会这样做:

    class MyTest
    {
      ...
      bool operator <(const MyTest &rhs) const
      {
        return m_first<rhs.m_first;
      }
    };
    

    【讨论】:

    • 这不是有效的 C++ 代码。它必须返回 bool 或其他东西
    • 感谢您的回答..但是如果将来我想按 m_second 排序,那么我必须提供函子。对吗?
    • 如果您现在需要以一种方式执行某种排序,并在其他时间对不同的数据集进行排序,那么您还可以指定一个函子进行比较。在这种情况下,使用仿函数,而不是内置的,因此两者之间没有冲突。我建议如果您需要,那么您可能应该删除比较运算符,以消除客户端代码混淆的可能性
    • 对这个老问题的疑问:问题是“降序”,但所有答案似乎都只进行正常的小于比较,我相信这会导致升序排序。我是否遗漏了什么,或者答案只是集中在这里更困难的部分?
    【解决方案2】:

    为你的结构写一个操作符

    【讨论】:

      【解决方案3】:

      定义运算符

      struct MyTest
      {
      ...
          bool operator<(const MyTest& a_test) const {
              return m_first < a_test.m_first;
          }
      };
      

      【讨论】:

      • 运算符只应取一个参数并与“this”进行比较。
      【解决方案4】:

      可以使用成员函数来实现,但独立函数是可行的方法。

      bool operator <(const MyTest &lhs, const MyTest &rhs)
      {
          return lhs.m_first<rhs.m_first;
      }
      

      为什么..

      Scott Meyers:非成员函数如何改进封装

      如果你正在编写一个函数 被实施为成员或 作为非朋友非会员,您应该 更喜欢将其作为非成员来实现 功能。这个决定增加了 类封装。你想的时候 封装,你应该认为 非成员函数。

      Surprised? Read on

      【讨论】:

        【解决方案5】:

        您应该在MyTest 中定义一个operator&lt;,它应该如下所示:

        bool operator<(const MyTest &other) const {
          return m_first < other.m_first;
        };
        

        【讨论】:

          【解决方案6】:

          http://ideone.com/3QLtP

          这没有定义操作符

          但是,穿越时间或编译过程很有趣。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-10-03
            • 1970-01-01
            • 2014-02-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-18
            相关资源
            最近更新 更多