Using Reference Types as return objects

I'm a little confused about reference types, I saw in the C++ tutorial on functions that you can pass arguments by reference to functions:

1
2
3
4
5
6
void duplicate (int& a, int& b, int& c)
{
  a*=2;
  b*=2;
  c*=2;
}


However, none of the tutorial demonstrates returning a reference type, and I have seen that done in examples outside of this site. For example, this compiles:

1
2
3
4
5
6
7
8
9
10
int& foo(int& bar) {
    return bar;
}

int main(int argc,char ** args) {
    int x = 3;
    int *y = &foo(x);
    const char* b = (&x) == (y) ? "yes" : "no";
    std::cout << "Are they the same pointer ? " << b << std::endl;
    // Are they the same pointer ? yes 


That made me wonder, if I omit the & in the return type, does that mean the return value is copied instead of passed by reference?

To research this, I wanted to modify the foo method to not return int&, but to return int instead, and see if the console still printed yes. Unfortunately though, I got a compilation error:

1
2
3
4
5
6
7
8
9
10
11
int foo(int& bar) {
    return bar; // no compilation error.
}

int main(int argc,char ** args) {
    int x = 3;
    int *y = &foo(x);  // compilation error: 
    // main.cpp:78:20: error: lvalue required as unary ‘&’ operand
    const char* b = (&x) == (y) ? "yes" : "no";
    std::cout << "Are they the same pointer ? " << b << std::endl;
}


I also wanted to know, how can I make my return type into a reference? Here is an example:

1
2
3
4
int& foo(int& bar) {
    return bar+1; // compilation error:
// invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
}


So my questions are why am I getting compilation errors in the above two exceptions? How can I resolve them? How can I make my return type be returned by reference?

and most importantly of all, if the return type is 'int' instead of 'int&', does that mean the variable gets copied when it gets returned? instead of being returned by reference?
most importantly of all, if the return type is 'int' instead of 'int&', does that mean the variable gets copied when it gets returned? instead of being returned by reference?
Yes. For something small like an int, it's a small distinction, but if you're returning a large class, then the difference can affect performance (because creating the copy is expensive).

why am I getting compilation errors in the above two exceptions?
In the first example (int *y = &foo(x)), think about that return value. It has to be stored somewhere? How long should it be kept around? There would be no point in making the assignment if the value disappears right away, but how long should the compiler keep it? Until the next statement? Until y goes away? Until the end of the program? All of those are bad ideas for different reasons. So the language designers decided that you can't take the address of a temporary value. That's the error you're getting.

The second case (return bar+1) is similar. How long should the value bar+1 be kept around?
First, I don't think the tutorial ever talked about these "temporary values". For example, I don't think it ever mentioned that you can't have a method return a local variable, I just learned that after trying, seeing compilation errors, and going through a lot of headaches.

think about that return value. It has to be stored somewhere?

You can say exactly the same thing about the working examples, I don't understand.

you can't take the address of a temporary value.


How is this taking the address of a temporary value:

1
2
3
int foo(int& bar) {
    return bar;
}


and this is not:

1
2
3
int& foo(int& bar) {
    return bar;
}


doesn't make any sense. Also, I don't think you answered how I can return something by reference.

In fact I can simplify the example:

1
2
3
4
5
6
7
8
int foo() {
   return 3; 
}

int main(int argc, char ** args) {
    int i = foo();
    int *p = &i;
}


above works, below does not:

1
2
3
4
5
6
7
int foo() {
   return 3; 
}

int main(int argc, char ** args) {
    int *p = &foo();
}


wth?
Last edited on
Topic archived. No new replies allowed.