仅与类的其他对象进行比较时,是否有任何理由不重载operator ==作为成员? [英] Is there any reason to not overload operator== as member, when only comparing to other object of the class?

查看:93
本文介绍了仅与类的其他对象进行比较时,是否有任何理由不重载operator ==作为成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在互联网上寻找答案,但找不到任何答案.给出的唯一原因似乎与与不同类型的对象(例如MyClass == int)进行比较有关.但是最常见的用例是将一个类实例与同一类的另一个实例进行比较,而不是与任何不相关的类型进行比较.

换句话说,我确实了解以下问题:

struct A {
    bool operator==(int b);
};

但是我找不到最明显的用例不使用成员函数的充分理由:

struct A {
    bool operator==(const A&);
};


另一方面,成员超载似乎有几个积极方面:

  • 不需要成为函数的朋友或为成员提供吸气剂
  • 它始终可供班级用户使用(尽管这也可能是不利的一面)
  • 查找没有问题(由于某种原因,这在我们的GoogleTests中似乎很常见)

是否将重载operator==作为非成员函数仅仅是为了使其与其他类中可能的重载保持一致?还是有其他原因使其成为非会员?

解决方案

好吧,在您的问题中,您确实忘记了const限定成员函数的功能,并且偶然地编写bool operator==(A&, const A&);会更困难.

如果您有隐式构造函数,具有隐式转换为A的类或具有优先级更高的operator==的基类,则成员函数在左侧时将不起作用,而在左侧在右边.尽管大多数时候隐式转换不是一个好主意,但是继承可能会导致问题.

 struct A {
    A(int);  // Implicit constructor
    A();

    bool operator==(const A&) const;
};

struct B : A {
    bool operator==(const B&) const;
};

void test() {
    A a;
    B b;
    // 1 == a;  // Doesn't work
    a == 1;
    // b == a;  // Doesn't work; Picks `B::operator==(const B&) const;`
    a == b;  // Picks `A::operator==(const A&) const`, converting `b` to an `A&`.
    // Equality is no longer symmetric as expected
}
 


将来,使用C ++ 20 operator<=>,您很可能总是将其实现为成员函数(即What are the basic rules and idioms for operator overloading? says "overload binary operators as non-member" as rule of a thumb.

  • Operator overloading : member function vs. non-member function? gives example mentioned above - if you were to use this operator with instance of another class/primitive type...
  • CppCoreGuidelines has a vague explanation "If you use member functions, you need two", which I assume applies to comparing with object of different type.
  • Why should operator< be non-member function? mentions that "non-member functions play better with implicit conversion", but it seems again the case of left-hand operand not being the instance of the class.
  • On the other hand, member overload seems to have a couple positive sides:

    • No need to befriend the function or to provide getters for members
    • It is always available to class users (although this might be the downside also)
    • No problems with lookup (which seems to be common in our GoogleTests for some reason)

    Is overloading operator== as non-member function just a convention to keep it the same with possible overloads in other classes? Or are there any other reasons to make it non-member?

    解决方案

    Well, in your question, you did forget to const qualify the member function, and it would be harder to write bool operator==(A&, const A&); by accident.

    If you had an implicit constructor, a class with implicit conversion to A or base class with an operator== with higher priority, the member function wouldn't work if it was on the left, but would if it was on the right. Although most of the time implicit conversions are a bad idea, inheritance could reasonably lead to a problem.

    struct A {
        A(int);  // Implicit constructor
        A();
    
        bool operator==(const A&) const;
    };
    
    struct B : A {
        bool operator==(const B&) const;
    };
    
    void test() {
        A a;
        B b;
        // 1 == a;  // Doesn't work
        a == 1;
        // b == a;  // Doesn't work; Picks `B::operator==(const B&) const;`
        a == b;  // Picks `A::operator==(const A&) const`, converting `b` to an `A&`.
        // Equality is no longer symmetric as expected
    }
    


    In the future, with the C++20 operator<=>, you will most likely always implement this as a member function (namely as auto operator<=>(const T&) const = default;), so we know that this guideline may change.

    这篇关于仅与类的其他对象进行比较时,是否有任何理由不重载operator ==作为成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆