user7476499
user7476499

Reputation: 83

What's the difference returning & and not?

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

Answers (1)

Bathsheba
Bathsheba

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

Related Questions