0

Here's my code. This runs, but it gives me an error when I remove the const from ostream& operator<< . Why?

As a side question, the error message shown is: cannot bind 'std::ostream {aka std::basic_ostream}' lvalue to 'std::basic_ostream&&' . How does this indicate that I'm missing a const?

#include <iostream>

using namespace std;

class pair_int{
public:
    int x;
    int y;
    pair_int(int x, int y):x(x),y(y){};
    friend ostream& operator<< (ostream & s, pair_int & c);
};
ostream& operator<<(ostream & s, const pair_int & c){
    s << c.x;
    s << ",";
    s << c.y;
    return s;
}
pair_int square(int x){
    return pair_int(x, x*x);

}
int main(int argc,char * argv []){
    int x;
    cin >> x;
    cout << square(x);

  return 0;
}
David Lui
  • 110
  • 4

1 Answers1

3

because the result of calling square() is an r-value, which can bind to a const l-value reference or an r-value reference, but not a mutable l-value reference.

This is by design, to prevent you from accidentally creating temporaries that you then mutate and throw away without meaning to.

(does not apply to rule-breaking Microsoft compilers)

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • Does it apply to other rule breaking compilers? :) :) – R Sahu Dec 04 '16 at 18:47
  • @RSahu I'm not aware of any other companies trying to hold back innovation by refusing to conform to internationally greed standards, but if you bring them to my attention I will happily call them out. – Richard Hodges Dec 04 '16 at 19:03
  • Unfortunately, I am not aware of any other companies. I work with MS compilers on a daily basis. The pain hits home for me. – R Sahu Dec 04 '16 at 19:10
  • @RSahu mingw and clang might be viable alternatives for you if you want a compiler that isn't a toy. – Richard Hodges Dec 04 '16 at 20:02
  • If you want to disable non-standard extensions with VC++, you can use `/Za`. And btw, clang and gcc also enable non-standard extensions by default. – Benjamin Lindley Dec 04 '16 at 20:12
  • @BenjaminLindley extensions yes. Blatant transgressions of the language, no. – Richard Hodges Dec 04 '16 at 20:13
  • What makes this a transgression, as opposed to an extension? Some people consider the rule a form of hand-holding that is not welcome in a low level language like C++, and so the relaxation of this rule is useful to them. – Benjamin Lindley Dec 04 '16 at 20:19
  • @BenjaminLindley It prevents successful compilation in a standards-conforming compiler. It's therefore a bug. Furthermore, it allows developers to compile code with semantics that they probably did not intend. Mutating a temporary is almost always an indication of a logic error. – Richard Hodges Dec 04 '16 at 20:21
  • The extensions turned on by gcc and clang do the exact same thing (prevent successful compilation in standards conforming compilers). And to the second point, that's the hand holding I was talking about. – Benjamin Lindley Dec 04 '16 at 20:23
  • "Mutating a temporary is almost always an indication of a logic error" (repeated) - handholding someone while they make an error is evil. – Richard Hodges Dec 04 '16 at 20:24