In C++ do you need to overload operator== in both directions?











up vote
32
down vote

favorite
2












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);
}









share|improve this question




















  • 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















up vote
32
down vote

favorite
2












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);
}









share|improve this question




















  • 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













up vote
32
down vote

favorite
2









up vote
32
down vote

favorite
2






2





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);
}









share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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'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














  • 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








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












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
}





share|improve this answer



















  • 5




    So theoretically one could implement different behaviour for Foo==String and String==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 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


















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.






share|improve this answer



















  • 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











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















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

























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
}





share|improve this answer



















  • 5




    So theoretically one could implement different behaviour for Foo==String and String==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 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















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
}





share|improve this answer



















  • 5




    So theoretically one could implement different behaviour for Foo==String and String==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 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













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
}





share|improve this answer














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
}






share|improve this answer














share|improve this answer



share|improve this answer








edited 2 days ago

























answered 2 days ago









StoryTeller

88.8k12179245




88.8k12179245








  • 5




    So theoretically one could implement different behaviour for Foo==String and String==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 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














  • 5




    So theoretically one could implement different behaviour for Foo==String and String==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 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








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












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.






share|improve this answer



















  • 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















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.






share|improve this answer



















  • 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













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.






share|improve this answer














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.







share|improve this answer














share|improve this answer



share|improve this answer








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














  • 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


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














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





















































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







Popular posts from this blog

QoS: MAC-Priority for clients behind a repeater

Ивакино (Тотемский район)

Can't locate Autom4te/ChannelDefs.pm in @INC (when it definitely is there)