4

I have the given code, which gets an error:

error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int' const int b = f(a++); ^

int f(int& a)
{
    return a;
}

int main() {
    // your code goes here
    int a = 5;
    int b = f(a++);
    std::cout << b << std::endl;
    return 0;
}

What the cause of this error ?

3 Answers3

5

You can't bind a temporary to a non-const reference.

Post-increment (a++) increments a and returns a temporary with a's old value.

Why are you passing by non-const reference? - it doesn't look like you're changing the parameter inside the function, just just pass by value or const reference.

If you were changing the parameter, what would you expect the behavior to be, considering a++ already changes it? Would the change be intuitive? Legal?

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

The postfix increment operator on an int returns a temporary value. A temporary value cannot bind to a non-const lvalue reference, because modifying that temporary doesn't make sense. You are trying to bind the temporary to an int&, which is giving an error.

To fix this, either use the pre-increment operator (++a), or take your argument by value (it's better to pass builtin types as value rather than const T&):

int f(int a)
{
    return a;
}
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
1

This function:

int f(int& a)

accepts non-const reference. Such references must always point to a valid objects, residing at certain memory locations (*).

Post incrementation works as follows:

 - save current value as `r`
 - increment original variable
 - return `r`

That's because result of post-incrementation is a temporary, yielding value from before incrementation. Such temporary must be passed either as value or const reference:

int f(int a) //This will work
int f(const int& a) //And this

(*) In fact, older compilers allowed for such constrcuts. For example, this code will compile under VC6:

struct T {};

void f(T& t)
{
}

int main()
{
    f(T());
}

However, such behaviour is not standard-compliant.

Mateusz Grzejek
  • 11,698
  • 3
  • 32
  • 49