In C++ do you need to overload operator== in both directions?
up vote
32
down vote
favorite
Say I am working with a class:
class Foo{
public:
std:string name;
/*...*/
}/*end Foo*/
and I provide an overload for operator==
bool operator==(const Foo& objA, const std::string& objB) {
return (objA.name == objB);
}
Do I also need to re-implement the same logic in reverse?
bool operator==(const std::string& objA, const Foo& objB) {
return (objA == objB.name);
}
c++ operator-overloading
|
show 3 more comments
up vote
32
down vote
favorite
Say I am working with a class:
class Foo{
public:
std:string name;
/*...*/
}/*end Foo*/
and I provide an overload for operator==
bool operator==(const Foo& objA, const std::string& objB) {
return (objA.name == objB);
}
Do I also need to re-implement the same logic in reverse?
bool operator==(const std::string& objA, const Foo& objB) {
return (objA == objB.name);
}
c++ operator-overloading
17
By the way, in c++20 you will be able to define just one new operator and the compiler will do the juggling. It'soperator <=>
.
– StoryTeller
2 days ago
4
related All you always dreamed to know about operator overloading but never cared to ask.
– YSC
2 days ago
2
The bigger question, IMO, is whether the concept of equality between aFoo
and a string is a valid concept or an inherent category error. A thing is not equivalent to its name, and the idea that it is is arguably part of what confuses people so much about pointers and references.
– cHao
yesterday
1
@StoryTeller - I must have missed the bit whereoperator<=>
will reorder arguments of different types (your first comment) - can you point to the section that specifies that?
– Toby Speight
yesterday
3
@TobySpeight - eel.is/c++draft/over.match.oper#3.4
– StoryTeller
yesterday
|
show 3 more comments
up vote
32
down vote
favorite
up vote
32
down vote
favorite
Say I am working with a class:
class Foo{
public:
std:string name;
/*...*/
}/*end Foo*/
and I provide an overload for operator==
bool operator==(const Foo& objA, const std::string& objB) {
return (objA.name == objB);
}
Do I also need to re-implement the same logic in reverse?
bool operator==(const std::string& objA, const Foo& objB) {
return (objA == objB.name);
}
c++ operator-overloading
Say I am working with a class:
class Foo{
public:
std:string name;
/*...*/
}/*end Foo*/
and I provide an overload for operator==
bool operator==(const Foo& objA, const std::string& objB) {
return (objA.name == objB);
}
Do I also need to re-implement the same logic in reverse?
bool operator==(const std::string& objA, const Foo& objB) {
return (objA == objB.name);
}
c++ operator-overloading
c++ operator-overloading
edited yesterday
StoryTeller
88.8k12179245
88.8k12179245
asked 2 days ago
hehe3301
296312
296312
17
By the way, in c++20 you will be able to define just one new operator and the compiler will do the juggling. It'soperator <=>
.
– StoryTeller
2 days ago
4
related All you always dreamed to know about operator overloading but never cared to ask.
– YSC
2 days ago
2
The bigger question, IMO, is whether the concept of equality between aFoo
and a string is a valid concept or an inherent category error. A thing is not equivalent to its name, and the idea that it is is arguably part of what confuses people so much about pointers and references.
– cHao
yesterday
1
@StoryTeller - I must have missed the bit whereoperator<=>
will reorder arguments of different types (your first comment) - can you point to the section that specifies that?
– Toby Speight
yesterday
3
@TobySpeight - eel.is/c++draft/over.match.oper#3.4
– StoryTeller
yesterday
|
show 3 more comments
17
By the way, in c++20 you will be able to define just one new operator and the compiler will do the juggling. It'soperator <=>
.
– StoryTeller
2 days ago
4
related All you always dreamed to know about operator overloading but never cared to ask.
– YSC
2 days ago
2
The bigger question, IMO, is whether the concept of equality between aFoo
and a string is a valid concept or an inherent category error. A thing is not equivalent to its name, and the idea that it is is arguably part of what confuses people so much about pointers and references.
– cHao
yesterday
1
@StoryTeller - I must have missed the bit whereoperator<=>
will reorder arguments of different types (your first comment) - can you point to the section that specifies that?
– Toby Speight
yesterday
3
@TobySpeight - eel.is/c++draft/over.match.oper#3.4
– StoryTeller
yesterday
17
17
By the way, in c++20 you will be able to define just one new operator and the compiler will do the juggling. It's
operator <=>
.– StoryTeller
2 days ago
By the way, in c++20 you will be able to define just one new operator and the compiler will do the juggling. It's
operator <=>
.– StoryTeller
2 days ago
4
4
related All you always dreamed to know about operator overloading but never cared to ask.
– YSC
2 days ago
related All you always dreamed to know about operator overloading but never cared to ask.
– YSC
2 days ago
2
2
The bigger question, IMO, is whether the concept of equality between a
Foo
and a string is a valid concept or an inherent category error. A thing is not equivalent to its name, and the idea that it is is arguably part of what confuses people so much about pointers and references.– cHao
yesterday
The bigger question, IMO, is whether the concept of equality between a
Foo
and a string is a valid concept or an inherent category error. A thing is not equivalent to its name, and the idea that it is is arguably part of what confuses people so much about pointers and references.– cHao
yesterday
1
1
@StoryTeller - I must have missed the bit where
operator<=>
will reorder arguments of different types (your first comment) - can you point to the section that specifies that?– Toby Speight
yesterday
@StoryTeller - I must have missed the bit where
operator<=>
will reorder arguments of different types (your first comment) - can you point to the section that specifies that?– Toby Speight
yesterday
3
3
@TobySpeight - eel.is/c++draft/over.match.oper#3.4
– StoryTeller
yesterday
@TobySpeight - eel.is/c++draft/over.match.oper#3.4
– StoryTeller
yesterday
|
show 3 more comments
2 Answers
2
active
oldest
votes
up vote
51
down vote
accepted
You do if you want to support comparisons where the string is on the left and the Foo
is on the right. An implementation won't reorder the arguments to an overloaded operator==
to make it work.
But you can avoid repeating the implementation's logic, though. Assuming your operator should behave as expected:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}
5
So theoretically one could implement different behaviour forFoo==String
andString==Foo
– hehe3301
2 days ago
39
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
19
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be!(lhs == rhs)
. That's whyoperator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.
– StoryTeller
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit fromequality_comparable<T, U>
and provideoperator==(T, U)
, it will supplybool operator==(const U&, const T&)
,bool operator!=(const U&, const T&)
, andbool operator!=(const T&, const U&)
for you.
– Kundor
yesterday
add a comment |
up vote
5
down vote
Yes, you do. Just like in lots of other languages, C++ takes sides and comparisons between two objects of different types will lead to calls to two different comparison operators depending on the order.
Of course, you want them to be consistent and not surprising, so the second should be defined in terms of the first.
10
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
51
down vote
accepted
You do if you want to support comparisons where the string is on the left and the Foo
is on the right. An implementation won't reorder the arguments to an overloaded operator==
to make it work.
But you can avoid repeating the implementation's logic, though. Assuming your operator should behave as expected:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}
5
So theoretically one could implement different behaviour forFoo==String
andString==Foo
– hehe3301
2 days ago
39
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
19
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be!(lhs == rhs)
. That's whyoperator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.
– StoryTeller
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit fromequality_comparable<T, U>
and provideoperator==(T, U)
, it will supplybool operator==(const U&, const T&)
,bool operator!=(const U&, const T&)
, andbool operator!=(const T&, const U&)
for you.
– Kundor
yesterday
add a comment |
up vote
51
down vote
accepted
You do if you want to support comparisons where the string is on the left and the Foo
is on the right. An implementation won't reorder the arguments to an overloaded operator==
to make it work.
But you can avoid repeating the implementation's logic, though. Assuming your operator should behave as expected:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}
5
So theoretically one could implement different behaviour forFoo==String
andString==Foo
– hehe3301
2 days ago
39
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
19
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be!(lhs == rhs)
. That's whyoperator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.
– StoryTeller
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit fromequality_comparable<T, U>
and provideoperator==(T, U)
, it will supplybool operator==(const U&, const T&)
,bool operator!=(const U&, const T&)
, andbool operator!=(const T&, const U&)
for you.
– Kundor
yesterday
add a comment |
up vote
51
down vote
accepted
up vote
51
down vote
accepted
You do if you want to support comparisons where the string is on the left and the Foo
is on the right. An implementation won't reorder the arguments to an overloaded operator==
to make it work.
But you can avoid repeating the implementation's logic, though. Assuming your operator should behave as expected:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}
You do if you want to support comparisons where the string is on the left and the Foo
is on the right. An implementation won't reorder the arguments to an overloaded operator==
to make it work.
But you can avoid repeating the implementation's logic, though. Assuming your operator should behave as expected:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}
edited 2 days ago
answered 2 days ago
StoryTeller
88.8k12179245
88.8k12179245
5
So theoretically one could implement different behaviour forFoo==String
andString==Foo
– hehe3301
2 days ago
39
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
19
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be!(lhs == rhs)
. That's whyoperator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.
– StoryTeller
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit fromequality_comparable<T, U>
and provideoperator==(T, U)
, it will supplybool operator==(const U&, const T&)
,bool operator!=(const U&, const T&)
, andbool operator!=(const T&, const U&)
for you.
– Kundor
yesterday
add a comment |
5
So theoretically one could implement different behaviour forFoo==String
andString==Foo
– hehe3301
2 days ago
39
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
19
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be!(lhs == rhs)
. That's whyoperator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.
– StoryTeller
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit fromequality_comparable<T, U>
and provideoperator==(T, U)
, it will supplybool operator==(const U&, const T&)
,bool operator!=(const U&, const T&)
, andbool operator!=(const T&, const U&)
for you.
– Kundor
yesterday
5
5
So theoretically one could implement different behaviour for
Foo==String
and String==Foo
– hehe3301
2 days ago
So theoretically one could implement different behaviour for
Foo==String
and String==Foo
– hehe3301
2 days ago
39
39
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
Yes, you could. But you definitely shouldn't.
– Matthieu Brucher
2 days ago
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
@StoryTeller Do we get op!= for free with this as !(op==) or should that be implemented both directions as well? (expecting the answer no)
– hehe3301
yesterday
19
19
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be
!(lhs == rhs)
. That's why operator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.– StoryTeller
yesterday
@hehe3301 - I'm afraid all the overloads you want will need to be implemented explicitly. Although again, the body can be
!(lhs == rhs)
. That's why operator <=>
generates so much excitement. Because it can cut down on a lot of boilerplate.– StoryTeller
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit from
equality_comparable<T, U>
and provide operator==(T, U)
, it will supply bool operator==(const U&, const T&)
, bool operator!=(const U&, const T&)
, and bool operator!=(const T&, const U&)
for you.– Kundor
yesterday
@hehe3301: You can use boost/operators.hpp, which provides classes to inherit from which fill in operators based on your provided ones. For instance, if you inherit from
equality_comparable<T, U>
and provide operator==(T, U)
, it will supply bool operator==(const U&, const T&)
, bool operator!=(const U&, const T&)
, and bool operator!=(const T&, const U&)
for you.– Kundor
yesterday
add a comment |
up vote
5
down vote
Yes, you do. Just like in lots of other languages, C++ takes sides and comparisons between two objects of different types will lead to calls to two different comparison operators depending on the order.
Of course, you want them to be consistent and not surprising, so the second should be defined in terms of the first.
10
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
add a comment |
up vote
5
down vote
Yes, you do. Just like in lots of other languages, C++ takes sides and comparisons between two objects of different types will lead to calls to two different comparison operators depending on the order.
Of course, you want them to be consistent and not surprising, so the second should be defined in terms of the first.
10
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
add a comment |
up vote
5
down vote
up vote
5
down vote
Yes, you do. Just like in lots of other languages, C++ takes sides and comparisons between two objects of different types will lead to calls to two different comparison operators depending on the order.
Of course, you want them to be consistent and not surprising, so the second should be defined in terms of the first.
Yes, you do. Just like in lots of other languages, C++ takes sides and comparisons between two objects of different types will lead to calls to two different comparison operators depending on the order.
Of course, you want them to be consistent and not surprising, so the second should be defined in terms of the first.
edited yesterday
answered 2 days ago
Matthieu Brucher
5,6241228
5,6241228
10
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
add a comment |
10
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
10
10
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
Re: "Just like in other languages": Overloading works sufficiently differently from one language to the next that I don't think this sort of sweeping statement is helpful.
– ruakh
yesterday
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53300142%2fin-c-do-you-need-to-overload-operator-in-both-directions%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
17
By the way, in c++20 you will be able to define just one new operator and the compiler will do the juggling. It's
operator <=>
.– StoryTeller
2 days ago
4
related All you always dreamed to know about operator overloading but never cared to ask.
– YSC
2 days ago
2
The bigger question, IMO, is whether the concept of equality between a
Foo
and a string is a valid concept or an inherent category error. A thing is not equivalent to its name, and the idea that it is is arguably part of what confuses people so much about pointers and references.– cHao
yesterday
1
@StoryTeller - I must have missed the bit where
operator<=>
will reorder arguments of different types (your first comment) - can you point to the section that specifies that?– Toby Speight
yesterday
3
@TobySpeight - eel.is/c++draft/over.match.oper#3.4
– StoryTeller
yesterday