1

I try to overload operator << and ++ (post and pre). This is part of my code, but I get error "e0349: no operator matches these operands". Could you tell me where I made a mistake? (C++, VS2022)

#include <iostream>
#include <string>

using namespace std;

class K {
    int x, y;
public:
    K(int a, int b) :x(a), y(b) {};
    K() :x(0), y(0) {};
    K operator++(int);
    K& operator++();
    friend ostream& operator<< (ostream & str, K & obj);
    
};

K K::operator++(int) {
    K temp(*this);
    x += 1;
    y += 1;
    return temp;
}
K& K::operator++() {
    x += 1;
    y += 1;
    return *this;
}
ostream& operator<<(ostream& str, K& obj) {
    str << "[" << obj.x << ", " << obj.y << "]";
    return str;
}


int main(int argc, char* argv[])
{
    K obj{10, 20};
    cout << obj++ << endl;  //here I get error
    cout << obj << endl;
    cout << ++obj << endl;

}
never_ever
  • 185
  • 1
  • 4
  • 13
  • 4
    Change `ostream& operator<<(ostream& str, K& obj)` to `ostream& operator<<(ostream& str, K const & obj)` as `obj++` returns a rvalue (temporary) and `K&` can't bind to a rvalue, but `K const &` can. – Richard Critten Nov 14 '22 at 12:47
  • Thank you, I hadn't thought of that because I was following the book I read. There seems to be mistake in my book. – never_ever Nov 14 '22 at 13:32
  • or there was a different context of insertion operator's use. Devil is in details. Even a templated operator may behave differently. – Swift - Friday Pie Nov 14 '22 at 16:41

1 Answers1

2

Simply the post-operator++ is written so that it returns a copy of the temporary value which can be used as rvalue but being that the signature of the insertion operator requires a reference of the value, it does not know how to retrieve the data passed as a copy. This is how you should modify the overloading function of the extract operator:

ostream& operator<<(ostream& str, K const& obj) {
    str << "[" << obj.x << ", " << obj.y << "]";
    return str;
}

You're simply telling the function that the passed value will have a constant reference that it won't change over time. So it is as if you are taking the reference of the copy value. I know it's very tricky as a thing but I should have cleared your minds enough

StellarClown
  • 160
  • 8
  • 1
    Thank you, now it is clear. I hadn't thought of that because I was following the book I read. There seems to be mistake in my book. – never_ever Nov 14 '22 at 13:33
  • It's an _insertion_ operator, not an extraction operator, which would look like `istream &operator>>(istream &, K &)`. An insertion operator with a non-const reference in its second argument is simply wrong. – Spencer Nov 14 '22 at 16:26
  • Apologizes. In a rush to answer, I wrote the wrong thing. I'll be more careful. In any case, I deigned to correct the answer. – StellarClown Nov 14 '22 at 16:31