代码之家  ›  专栏  ›  技术社区  ›  Head Geek

比较函子类型与运算符<

  •  10
  • Head Geek  · 技术社区  · 17 年前

    Google C++ Style Guide 这个 section on Operator Overloading 建议不要超载 任何 运营商(“罕见、特殊情况除外”)。具体而言,它建议:

    特别是不要超载 operator== operator< 只是为了 创建相等和比较函子 声明容器时键入。

    我对这样一个函子的样子有点模糊,但我的主要问题是, 为什么? 您想为此编写自己的函子吗?你不觉得吗 操作员< std::less<T> 功能,更简单?使用一个比另一个有什么好处吗?

    7 回复  |  直到 17 年前
        1
  •  16
  •   Konrad Rudolph    17 年前

    除了更基本的类型外,小于运算并不总是微不足道的,甚至相等也可能因情况而异。

    想象一下,一家航空公司希望为所有乘客分配一个登机号码。这个数字反映了登机顺序(当然)。现在,什么决定了谁先于谁?您可以按照客户注册的顺序进行操作,在这种情况下,“小于”操作将比较签入时间。你也可以考虑买票的价格比现在的票价要低。

    等等。总而言之,定义一个 operator < Passenger 尽管可能要求旅客在分拣集装箱内,但仍需进行分类。我想这就是谷歌所警告的。

        2
  •  6
  •   LogicStuff    10 年前

    一般来说,定义 operator<

    当您需要多种方法来比较特定类型时,您可能希望使用函子。例如:

    class Person;
    
    struct CompareByHeight {
        bool operator()(const Person &a, const Person &b);
    };
    
    struct CompareByWeight {
        bool operator()(const Person &a, const Person &b);
    };
    

    在这种情况下,可能没有一个好的“默认”方式来比较和排序人员,因此无法定义 使用函子可能更好。你也可以说,一般来说,人是按身高排序的,等等 操作员< 只是打电话 CompareByHeight ,任何需要按重量订购的人都必须使用 CompareByWeight 明确地

    通常情况下,问题在于定义函子由类的用户决定,因此,每当类需要在有序容器中使用时,您往往会得到同一事物的许多重新定义。

        3
  •  5
  •   James Curran    17 年前

    我的感觉是,一个人应该尽可能地使你的类成为一流的对象,对我来说,这意味着让他们理解尽可能多的操作符。

    我已经有一段时间没有写函子了,但它看起来像这样:

    class MyClass {....}
    
    class LessThanMyClass : std:binary_function<MyClass, MyClass, bool>
    {
        public bool operator()(MyClass lhs, MyClass rhs) 
        {   return /* determine if lhs < rhs */ ; }
    }
    
    vector<MyClass> objs;
    std::sort(objs.begin(), objs.end(), LessThanMyClass());
    

    }

        4
  •  3
  •   camh    17 年前

    我认为不定义运算符背后的信息<排序是集合的属性,而不是对象的属性。相同对象的不同集合可能具有不同的顺序。因此,在指定集合类型时,应该使用单独的函子,而不是运算符<。

    记住,当我们设计对象模型时,我们只是对现实世界的一个子集建模。在现实世界中,可能有无数种不同的方法来对同一类的对象进行排序,但在我们正在工作的应用程序域中,可能有一种方法是相关的。

    如果代码发展到需要第二种排序,而这种排序与第一种排序同样相关,则应重构该类以删除运算符<并将两个排序函数放在单独的函子中。这表明没有一个排名比其他排名更重要。

    当然,每一条规则都有例外。如果你不知道是否应该破例,你可能不应该。经验将是你的向导。

        5
  •  3
  •   LogicStuff    10 年前

    我可能不会像谷歌风格的指南那样深入。

    我认为他们的意思是当你超载时 operator< operator==

    如果您需要比较器的唯一目的是将项放入集合中,那么最好为该上下文专门设置一个函数,而不是在所有上下文中应用运算符。

    您可能希望按时间顺序对采购订单进行排序,但一般来说,按总价进行比较是有意义的。如果我们超载 操作员< 为了比较日期以便将其加载到集合中,我们引入了另一个客户可能滥用我们的数据的风险 他们可能会认为这与总价格相比。

        6
  •  2
  •   Community Mohan Dere    9 年前

    函子是具有 operator () . 在这种情况下,该方法将采用所比较类型的两个参数,并返回一个 bool

    编辑:建立在什么基础上 James Curran 也就是说,可以在类中定义函子。例如:

    class MyClass
    {
        struct LessThan : public std::binary_function<MyClass, MyClass, bool>
        {
            bool operator()(const MyClass & first, const MyClass & second) const
            {
                return first.key < second.key;
            }
        };
    };
    
        7
  •  1
  •   LogicStuff    10 年前

    具有讽刺意味的是,函子还需要重写运算符(函数调用运算符)- operator () ),所以我不确定他们的观点是什么。