1

For example:

void do_something(int& x){ 
//this function asks for a reference to an int,
//since the type of its argument is int&
}

int main() { 


    int x = 4; //the variable x is simply an int; it isn't a reference?
    int& y = x; //the variable y is a reference to x

    do_something(y); //this works, as expected                

    do_something(x);      
    //this calls the method with an int, instead of a reference. 
    //Why does this work? It's not giving the function what the function is
    //asking for. 
}

Why does do_something(x) work? It's not giving the function what the function is asking for. The only explanation I can come up with is that the int being passed to the function has a reference created for it, and that reference is what ends up being passed to the function.

James Ronald
  • 685
  • 1
  • 6
  • 13
  • a reference can be seen as an implicit pointer, it was created to reduce complexity, probably because lot of developpers are lost with pointers – Pierre Emmanuel Lallemant May 23 '19 at 15:40
  • 1
    in a wider sense `x` references itself – 463035818_is_not_an_ai May 23 '19 at 15:40
  • @PierreEmmanuelLallemant I never understood how that analogy is supposed to help understanding references. Also in this particular case. To pass a pointer you would have to use the addressof operator, passing pointers is different from passing references – 463035818_is_not_an_ai May 23 '19 at 15:42
  • 1
    @PierreEmmanuelLallemant An important difference between pointers and references is that references cannot be uninitialized, but pointers can be `nullptr` to signify "points to nothing". – Jesper Juhl May 23 '19 at 15:43
  • 2
    Looks like you can benefit from a good C++ book, you can find curated list here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – SergeyA May 23 '19 at 15:44
  • 2
    @PierreEmmanuelLallemant, no reference is NOT an implicit pointer, it it's best NOT to understand it this way. – SergeyA May 23 '19 at 15:45
  • 2
    @JesperJuhl references are just not pointers. Comparing reference to a pointer might be justified when someone is coming from the language which doesn't have references (but has pointers, like C), but if C++ is learned from the ground up, there is simply no reason to invoke pointers when talking about references. – SergeyA May 23 '19 at 15:46
  • @SergeyA I don't disagree. I just wanted to point out some important differences. It seemed relevant. – Jesper Juhl May 23 '19 at 15:50
  • I didn't tell it WAS an implicit pointer, but that it can be seen as it. The reference simulates the pointer's use, without having to use &var to refer to the adress of the variable. Reference is a restriction of pointer, you cannot do arithmetic on it.The adress is managed by the compiler, you don't need anymore to think about address. – Pierre Emmanuel Lallemant May 23 '19 at 15:53
  • @PierreEmmanuelLallemant unfortunately this is way oversimplified point of view. The same way you can say that any variable is like a pointer to some memory, compiler just let you use it without dereference. – Slava May 23 '19 at 15:57
  • Which is technically true. And when learning C++ from bottom, pointers already exist, and existed way before references. – Pierre Emmanuel Lallemant May 23 '19 at 15:58
  • @PierreEmmanuelLallemant yes from some point of view that is true, but does it help to understand semantics of using object or reference vs pointer? I doubt. – Slava May 23 '19 at 16:00
  • 1
    @PierreEmmanuelLallemant Depends on what you mean by "from bottom". It is entirely reasonable to learn references before learning about pointers. A strategy of learning C++ features in chronological order is not necessarily an ideal one. – eerorika May 23 '19 at 16:06
  • @SergeyA actually I've been reading a Tour of C++ 2nd edition haha. Would you expect a question like this to be answered by that book? Maybe I'm approaching learning the wrong way – James Ronald May 23 '19 at 16:13

4 Answers4

7

One way to look at a reference is to think of it as an alias. It's just a new name for an existing object, and you can use the existing name or the new one you gave it. That means

void do_something(int& x)

doesn't really need a reference passed to it. What it is saying is that x will be a reference to some int object. Looking at it that way it makes perfect sense that you can pass an int to do_something because you are giving it the int that x will refer to.

This also works the other way around. If you instead had

void do_something(int x)

you could still pass y to it since y is just the name for an int.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 6
    `One way to look at a reference is to think of it as an alias.` I dare say, it is the best way to look at reference, and potentially the only correct one. – SergeyA May 23 '19 at 15:47
  • 2
    @SergeyA Pretty Much. It gets a little tricky with classes since reference members normally take up space so there is more to just being an alias, but those are implementation details that don't need to to be taught at the start. The "it's just an alias" way works until they have a good foundation and are ready to start diving into the deep end. – NathanOliver May 23 '19 at 15:58
  • Thank you for the response, that makes sense! So if `void do_something(int x)` is identical to `void do_something(int& x)`, what is the point of including the &? In the book I'm reading (Tour of C++ 2nd edition) the author seems to always use the latter version instead of the former, so I'm guessing there's a reason – James Ronald May 23 '19 at 17:10
  • 2
    @JamesRonald They are not identical. With `void do_something(int& x)` any change you make to `x` in the function will be reflected in the variable you passed to the function. With `void do_something(int x)` any changes made to `x` in the function will not show up in the variable you passed to the function. – NathanOliver May 23 '19 at 17:18
  • @NathanOliver oh wow that's quite the difference then! I see that C++ is different than Java in this sense. Thank you for the help! – James Ronald May 23 '19 at 17:41
  • 2
    @JamesRonald When learning C++, do yourself a favor and pretend that Java doesn't exists. They are pretty different languages and have a lot of things that are different, even if they syntactically look the same. – NathanOliver May 23 '19 at 17:53
5

If a reference could only be bound to other references, then there would be no way of referring to an object.

do_something(x) works just the same as int& y = x does. In both cases a reference variable is bound to an object. In case of the function call, the reference variable is a parameter.

The only explanation I can come up with is that the int being passed to the function has a reference created for it

All function parameters - and more generally all variables (function parameters are essentially local variables) - are "created" (although it depends on what is meant by "creation"). If the variable is a reference, then a reference is created. If the variable is not a reference, then an object is created.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thank you for the response! So I understand now that references should just be thought of as aliases for the object they refer to. With that in mind, is there any meaningful difference between a reference being created and a object being created (described in your last sentence)? – James Ronald May 23 '19 at 16:12
  • @JamesRonald No difference in general. They're just different types. – eerorika May 23 '19 at 16:19
2

You can imagine the function

void do_something(int& parn){ 
    //...
}

and its call

int x = 4; //the variable x is simply an int; it isn't a reference?

do_something(x);   

the following way

int x = 4; //the variable x is simply an int; it isn't a reference?

do_something(x);  

// ...

void do_something( /* int& parn */ ){
    int &parm = x;  
    //...
}

That is the function parameter (that is a local variable of the function) that has a referenced type is initialized by the argument. Now the parameter parm references the variable x. It can be considered as an alias for the variable x within the function.

The only difference between this reference declaration inside the function

void do_something( /* int& parn */ ){
    int &parm = x;  
    //...
}

and this declaration in main

int& y = x;

is that the variable parm (the function parameter) has block scope of the function.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

"Why can a function which takes a reference be given just an object (and not a reference)? Is a reference automatically made?"

Yes. A reference to the object you pass is formed when you call the function.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70