operator==, member function or free function

  • Thread starter =?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=
  • Start date
?

=?ISO-8859-1?Q?Mattias_Br=E4ndstr=F6m?=

Hello!

I'm just curious as to what the group recommends when implementing
operator==? Should it be a member function or a free function. The
reason I might want to have it as free function is to get type
conversion on the left hand side argument.

class Decimal() {
public:
Decimal(std::string);
}

Decimal d("1.2");
d == "1";
"1" == d;

As fas as I understand this is the recomended way to implement the
arithmetic operators. Does the same arguments hold for operator==?

Regards,
Mattias
 
D

Donovan Rebbechi

Hello!

I'm just curious as to what the group recommends when implementing
operator==? Should it be a member function or a free function. The

Make it a free function unless it needs to be a member function. If
it has to be a member function, you can write the other version in
terms of the member function.
reason I might want to have it as free function is to get type
conversion on the left hand side argument.

class Decimal() {
public:
Decimal(std::string);

I hope this isn't real code. This constructor should be
declared explicit to prevent implicit conversion, and the
argument should probably be passed by reference (this is
a general rule of thumb for class types). There are places
where one may want to permit implicit conversion, but where
the types are fundamentally different, it isn't recommended.
e.g. this shouldn't be allowed: Decimal x; x += "2.3";

btw, better to go with least common denominator and use a const
char* argument, not a string argument.

Also, I'd question even having an operator== if it's a
floating point class.

Cheers,
 
R

Rolf Magnus

Donovan said:
Make it a free function unless it needs to be a member function. If
it has to be a member function, you can write the other version in
terms of the member function.

Yep, that's the usual reason for making it a non-member. (to the OP) So why
do you ask? Do you have any reason to make it a member?
I hope this isn't real code. This constructor should be
declared explicit to prevent implicit conversion,

Unless he wants such a conversion.
and the argument should probably be passed by reference (this is
a general rule of thumb for class types).

In this case, by reference to const, i.e.

Decimal(const std::string&);
There are places where one may want to permit implicit conversion, but
where the types are fundamentally different, it isn't recommended.
e.g. this shouldn't be allowed: Decimal x; x += "2.3";

It isn't anyway.
btw, better to go with least common denominator and use a const
char* argument, not a string argument.

I'd say that depends on how the constructor is using it. If it's parsing the
string using a stringstream, it needs an std::string anyway. Then there is
not much sense in needing to make a const char* out of an std::string by
using c_str(), just to copy that into a new std::string.
Also, I'd question even having an operator== if it's a floating point
class.

It might be a fixed point class.
 
R

Richard Herring

Rolf Magnus said:
Donovan Rebbechi wrote:
[...]
Also, I'd question even having an operator== if it's a floating point
class.

It might be a fixed point class.

Even if it's not, that's no reason not to define equality.

Granted, _arithmetic_ operations on floating-point numbers are not
always reversible, so there's no guarantee that (a+b-b)==a, but there's
more to numbers than arithmetic.

One often wants to sort on a set of floating values, and that requires
not arithmetic but a strict weak ordering. Floating-point numbers
(except maybe NaN ;-) have a natural ordering defined by operator< which
has all the right properties. Given that, there's an obvious definition
for operator== (neither < nor >) which is consistent with that ordering,
and it would be pointless not to define these operators in the obvious
way.
 
R

Rolf Magnus

Richard said:
Rolf Magnus said:
Donovan Rebbechi wrote:
[...]
Also, I'd question even having an operator== if it's a floating point
class.

It might be a fixed point class.

Even if it's not, that's no reason not to define equality.

Granted, _arithmetic_ operations on floating-point numbers are not
always reversible, so there's no guarantee that (a+b-b)==a, but there's
more to numbers than arithmetic.

One often wants to sort on a set of floating values, and that requires
not arithmetic but a strict weak ordering.

You don't need operator== for that.
Floating-point numbers (except maybe NaN ;-) have a natural ordering
defined by operator< which has all the right properties. Given that,
there's an obvious definition for operator== (neither < nor >) which is
consistent with that ordering, and it would be pointless not to define
these operators in the obvious way.

If there is not much use for operator==, then it's not poinless to not
define it. Same for operator!=, to add another "not". ;-)
 
R

Richard Herring

Rolf Magnus said:
Richard said:
Rolf Magnus said:
Donovan Rebbechi wrote:
[...]

Also, I'd question even having an operator== if it's a floating point
class.

It might be a fixed point class.

Even if it's not, that's no reason not to define equality.

Granted, _arithmetic_ operations on floating-point numbers are not
always reversible, so there's no guarantee that (a+b-b)==a, but there's
more to numbers than arithmetic.

One often wants to sort on a set of floating values, and that requires
not arithmetic but a strict weak ordering.

You don't need operator== for that.

I know. Read on:
.... and having == (or !=) means you can then add searching to the list
of algorithms that can be used on the class.
If there is not much use for operator==, then it's not poinless to not
define it. Same for operator!=, to add another "not". ;-)

Sure, if that's truly the case. No point in cluttering the interface
with unnecessary stuff.

But searching and sorting are so common that it's quite likely that the
_user_ of the class will want to do them, even if the designer didn't
consider the possibility.

But none of those considerations has anything to do with whether the
class happens to be some kind of implementation of floating-point
arithmetic. And _that_ was my point.
 
D

Donovan Rebbechi

Unless he wants such a conversion.

Sure, but it's the sort of thing one should think twice about "wanting".
In this case, by reference to const, i.e.

Decimal(const std::string&);
yep


It isn't anyway.

If you tweak the constructor to take const char* instead of string, it is.
I'd say that depends on how the constructor is using it. If it's parsing the
string using a stringstream, it needs an std::string anyway. Then there is
not much sense in needing to make a const char* out of an std::string by
using c_str(), just to copy that into a new std::string.

Reduces dependencies by moving the use of std::string from interface to
implementation. In some contexts, a good thing.
It might be a fixed point class.

Yep.

Cheers,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top