0

I am currently trying to understand operator overloading in C++.I tried overloading operator '!=' in the following code:

#include <iostream>
using namespace std;
class MyClass{
    int a=0;int b=0;
    public:
    MyClass() = default;
    MyClass(int x,int y){a = x;b=y;}
    MyClass(const MyClass& ob){a = ob.a;b = ob.b;}
    MyClass& operator=(const MyClass& ob) = default;
    bool operator!=(const MyClass& ob){
        return a!=ob.a && b!=ob.b;
    }
};
int main() {
    MyClass ob{112,981};
    
    /* This Works
    MyClass ob2{211,121};
    if(ob!=ob2){ */
    
    /*This also works
    if(ob.operator!=({211,121})){ */
    
    //Why does this does not work ??
    if(ob!={211,121}){
        cout<<"Operator != overloaded"<<endl;
    }
    return 0;
}

In the main function, the if(ob!={211,121}){...} does not work and leads to following compilation error:

prog.cpp: In function ‘int main()’:
prog.cpp:25:9: error: expected primary-expression before ‘{’ token
  if(ob!={211,121}){
         ^
prog.cpp:25:9: error: expected ‘)’ before ‘{’ token

Moreover to my surprise, When I tried the following variation to implement the same logic, it worked:

 if(ob.operator!=({211,121})){
   return a!=ob.a && b!=ob.b;
 }

Can someone please explain the reason?

https://godbolt.org/z/9WKf3f97Y

Marek R
  • 32,568
  • 6
  • 55
  • 140
abhishek gupta
  • 359
  • 1
  • 12

1 Answers1

4

The compiler tells you. For instance GCC says:

$ g++ -std=c++17 source.cpp && ./a.out
source.cpp: In function ‘int main()’:
source.cpp:24:12: error: expected primary-expression before ‘{’ token
   24 |     if(ob!={211,121}){
      |            ^
source.cpp:24:12: error: expected ‘)’ before ‘{’ token
   24 |     if(ob!={211,121}){
      |       ~    ^
      |            )

whereas Clangd (I use it in the IDE) goes straight to the point:

Initializer list cannot be used on the right hand side of operator '!=' [init_list_bin_op]

so you simply can't do something != {init list}. Notice that this is true in much simpler cases:

int x = {}; // ok
x != {};    // not ok

Notice that this has no relation with the rhs of != being an rvalue. Indeed ob != MyClass{211,121} works, and MyClass{211,121} is an rvalue.

As regards to why ob.operator!=({211,121}) works fine, it's because it's a function call to operator!= member function, which is known to take a const MyClass&, which the {211,121} can be converted to.

Concerning why {init-list} is forbidden after operators, it is throughly explained here.

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • I was also using GCC. So, the real reason is that {211,121} is considered an Initalizer list and that it cannot be used on the right side of operator != . Is that correct for GCC as well even if the error messages do not directly say that like clang ? – abhishek gupta Apr 28 '21 at 09:44
  • 1
    It reads `expected primary-expression before ‘{’`, which in other words means it did not expect `{` after what precedes it, that is after `!=`. This being said, whether the standards puts one or the other (or in a third) way, I don't know. You can ask a new question with the _language-lawyer_ tag, if you want to know more. (Btw, thanks to this answer, I've been awarded the bronze c++ badge!) – Enlico Apr 28 '21 at 09:45
  • I would say this is not reasons explanation, but just explanation of error message. – Marek R Apr 28 '21 at 09:53
  • Wondering why does the operator!=(...) works fine? – abhishek gupta Apr 28 '21 at 09:53
  • @abhishekgupta, added a comment about that. – Enlico Apr 28 '21 at 10:05
  • @MarekR, I guess you refer to _why doesn't the compiler understand I'm trying to use `operator!=` memeber function when doing `ob != {smth}`?_ I admit I don't know the answer. Probably it's written [here](https://en.cppreference.com/w/cpp/language/operator_comparison), but I'm not sure. – Enlico Apr 28 '21 at 10:09
  • 1
    I know the answer, but I'm unable to explain this nicely (using correct terminology). I think language layer is needed for that. – Marek R Apr 28 '21 at 10:22
  • 1
    @MarekR, added a link to the [relevant answer](https://stackoverflow.com/questions/11420448/initializer-lists-and-rhs-of-operators) – Enlico Apr 28 '21 at 10:34