Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Defining operator ==

25 views
Skip to first unread message

Bo Persson

unread,
Jan 7, 2018, 5:35:42 PM1/7/18
to
On 2018-01-07 19:04, Stefan Ram wrote:
> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>>> inline bool operator ==( const pair & l, const pair & r )
>>> bool operator==(Ring const &r) const {
>> nor does one add more public members to the class, but one
>> rather moves the declaration of »operator==« into the class
>> specifier.
>
> But then, (begin of quotation)
>
> C.86: Make == symmetric with respect to operand types
> and noexcept
>
> Reason: Assymetric treatment of operands is surprising
> and a source of errors where conversions are possible.
> == is a fundamental operations and programmers should be
> able to use it without fear of failure.
>
> Example:
>
> class X {
> string name;
> int number;
> };
>
> bool operator==(const X& a, const X& b) noexcept { return a.name==b.name && a.number==b.number; }
>
> Example, bad:
>
> class B {
> string name;
> int number;
> bool operator==(const B& a) const { return name==a.name && number==a.number; }
> // ...
> };
>
> B's comparison accepts conversions for its second
> operand, but not its first.
>
> (end of quotation)
>

This of course assumes that you WANT a conversion of the operands, and
intend to compare a derived class to the base class.

If not, the member works fine.


Bo Persson


Marcel Mueller

unread,
Jan 7, 2018, 6:37:24 PM1/7/18
to
On 07.01.18 17.33, Stefan Ram wrote:
> For a class, Herb Sutter once recommended to write
>
> inline pair operator +( pair result, pair const & other )
> { result += other; return result; }

Whether this is efficient or not depends. If the component types are
rather complex and if you use C++11 or above I would /not/ recommend
this. Copying could be expensive. And in contrast to the returned value
RVO and move semantics are not possible for the parameters.
Furthermore I dislike asymmetric definitions of symmetric operators.

Typically I would expect something like
inline friend pair operator +( pair const& l, pair const& r )
{ return pair(l.x + r.x, l.y + r.y); }
within the class. The "friend" will automatically create a free function
instead of a class member. This is common practice.

> outside of the class specifier and then in the class specifier:
>
> pair & operator +=( const pair & o )
> { x += o.x; y += o.y; return *this; }

Just fine.

> . So, now I want to implement
>
> inline bool operator ==( const pair & l, const pair & r )
>
> outside of the class specifier (as I believe it should
> be). Should I now write
>
> l.x == r.x && l.y == r.y
>
> into the definition of »operator ==« and add it as a friend
> to the class (»x« and »y« are private) or should I rather write
>
> inline bool operator ==( const pair & l, const pair & r )
> { return l.equals( r ); }
>
> and add a function
>
> bool equals( const pair & other )const
> { return this->x == other.x && this->y == other.y; }
>
> within the class specifier?

This is an option. But I would recommend the Java like, asymmetric
equals method only if you really need it.
Otherwise I recommend the same procedure as for operator+:

inline friend bool operator ==( const pair & l, const pair & r )
{ return l.x == r.x && l.y == r.y; }


Marcel
0 new messages