Reputation: 83
I still haven't figured out how the &
works in the compiler.
To figure it out, I tried disassembling the code below:
private:
int data;
public:
int& at()
{
return data;
}
int at()
{
return data;
}
const int& result = mymay.at(); //call the two functions
I find that int& at()
returns an address, and int at()
returns a value; the compiler first writes the value to a memory, then "result"'s address was set to it.
So I understand that int at()
will return a copied one.
I also understand that it's best practice to write friend ostream& operator<<(ostream &os , const A &obj)
But I wonder if it's correct: in the below code, A &get1()
returns an l-value
, and A get2()
returns an r-value
.
#include <iostream>
using namespace std;
class A
{
public:
A &get1(){
return *this;
}
A get2(){
return *this;
}
friend ostream& operator<<(ostream &os , A &obj){
cout<<"An l-value function called."<<endl;
return os;
}
friend ostream& operator<<(ostream &os , A &&obj){
cout<<"An r-value function called."<<endl;
return os;
}
};
int main()
{
A tmp;
cout<<"get1: "<<tmp.get1()<<"get2: "<<tmp.get2()<<endl;
return 0;
}
Actual results:
An l-value function called.
An r-value function called.
Upvotes: 0
Views: 112
Reputation: 234635
The version of at
that returns a reference allows you to modify the member datum data
via that reference:
mymay.at() = 1;
will set data
in the instance of mymay
to 1. So mymay.at()
is an l-value: i.e. it can be placed on the left hand side of an assignment.
The version of at
that returns a value will not allow you to do that. It's not an l-value.
Your second point, an l-value cannot bind to an rvalue reference &&
wheres an anonymous temporary can. Overload resolution for your cout
is unambiguous which accounts for the output of your program.
Upvotes: 6