Reputation: 631
Below is a simple example that produces errors (VS 2019):
C2664 'void foo(std::string &)': cannot convert argument 1 from 'std::string' to 'std::string &'
using namespace std;
void foo(string& input) {
cout << "Foo is: " << input << endl;
}
string getInput() {
return string("abc");
}
int main()
{
foo(getInput());
}
I don't understand the error. getInput() returns a string. Why can't that string be passed directly to the foo() function as a reference just like any local or member variable can be passed by reference to the foo() function? As the error message suggests, making the string argument a const makes the error go away. Why would that be?
Update: I thought about this question some more after considering the response and a couple links that I posted below. I think the core issue here is that the return value of getInput() is a temporary variable. If I had instead copied the result of getInput() into a local or global variable and then passed that to foo(), there would be no error. I think the compiler does not "like" passing the temporary variable that stores the result of getInput() by reference because how long will the temporary variable stay valid? Obviously, it must stay valid immediately after getInput() returns, but how much longer after that?
Upvotes: 4
Views: 1517
Reputation: 1445
This is because a const reference can bind to both lvalue and rvalue. This makes sense as being marked as const, the value cannot be changed even if the input is an rvalue. If the value is not const, you then have the option of editing the non-const reference inside the function. This would make no sense as the input was an rvalue.
Upvotes: 5