# Returning a reference

## Recommended Posts

I always thought that you are required to give a function the exact same type that it specifies in its definition. Here is a snippit of code that I was looking at that assigns a vector to a function that asks for a reference.
[source lang=cpp]
string& foo(vector<string>& inventory, int i);

int main()
{
vector<string> inventory;
cout << foo(inventory, 0) << "\n\n";
}


The "vector<string>&" appears to call for a reference to a vector of strings. Inventory is only defined as a vector of strings here: "vector<string> inventory." How can we use inventory as a value for the function inventory, since it isn't a reference? Does this statement say that vector<string>& inventory = vector<string> inventory, that is, does make declare and define a reference?

##### Share on other sites
Consider this:
vector<string> inventory;vector<string>& referenceToInventory = inventory;//!!!referenceToInventory.resize(10);if( inventory.size() == 10 )  cout << "yay references work";

On the line commented as "!!!", a reference is created that "aliases" a value.

This is what is happening when you call that function. It wants a reference, you give it a value, so it's reference variable is assigned to/aliases your value.

##### Share on other sites
When you see a reference in a function argument list, think 'pass-by-reference' rather than 'pass a reference.' The two phrases say exactly the same thing, but the first one does a better job of conveying what's really going on: 'the vector is being passed by reference to the function' as opposed to 'the function is receiving a reference to an existing vector.' Both are true, but the former is a more helpful way to think about it.

As for why it works: consider it hand-waving on the part of your compiler. When it sees a function with a pass-by-reference argument, and it sees the function used with syntax for pass-by-value, it waves its little digital fingers and reference-izes the thing for you. This can be a blessing and a curse; on the one hand, you don't have to worry about it. On the other... you probably won't worry about it. Make sure you keep track of when variables are being passed by-reference and by-value, and try to use pass-by-reference-to-const as much as possible.

##### Share on other sites
Quote:
 Original post by HodgmanConsider this:*** Source Snippet Removed ***On the line commented as "!!!", a reference is created that "aliases" a value.This is what is happening when you call that function. It wants a reference, you give it a value, so it's reference variable is assigned to/aliases your value.

awesome. Just as I thought. Now what if i were to give the function a reference to inventory to begin with? Would the function make a reference to my reference? or would it simply use it as opposed to creating a new one?

the former sounds sort of inefficient and pointless, but you never know?

Also, does the same process apply for pointers? If I pass a value to a function that asks for a pointer, will it have a pointer point to my value?

##### Share on other sites
Its an optimization. You just call the function with your value. That requires the function to copy the value on the stack. You can think for yourself what that means if you have quite a huge vector. So the optimization is that the function declares its parameter as reference. You still hand it the value but it does not copy the value but uses roughly spoken the memory address of your value to access the data without copying it. You value "gets referenced" by the compiler automatically so you do not need to create a reference yourself.

##### Share on other sites
Quote:
 Original post by zoner7Would the function make a reference to my reference? or would it simply use it as opposed to creating a new one?

If you hand in the correct type (a reference in this case) it will use it because there is no need to "reinterpret" the incoming parameter to make its type fit.

Quote:
 Original post by zoner7Also, does the same process apply for pointers? If I pass a value to a function that asks for a pointer, will it have a pointer point to my value?

Same goes here. If the function asks for a pointer and you give it a pointer the function takes it as pointer. But if you try to hand in a value the compiler won't accept that. In can reference values but it is not allowed to make a pointer from a value:

void foo(int *);int i = 0;foo(i);  // <- wont even compilefoo(&i); // <- is the way to go here, note that now foo can change actual value of i

Note that in this case the & means that you access the address of i as opposed to int &b = i; which would be a reference to i and not a pointer. To create you even more headache you can also create references to pointers [grin] ...

##### Share on other sites
Quote:
 Original post by zoner7awesome. Just as I thought. Now what if i were to give the function a reference to inventory to begin with? Would the function make a reference to my reference? or would it simply use it as opposed to creating a new one?the former sounds sort of inefficient and pointless, but you never know?Also, does the same process apply for pointers? If I pass a value to a function that asks for a pointer, will it have a pointer point to my value?

I'm pretty sure that references-to-references are actually forbidden by the C++ standard. I might be crazy, but I think I read that somewhere. So, in answer to your first question: the function would just get a reference to your value, as normal.

As for pointers, think of them just like any other value-type. When you pass a pointer, the pointer is passed by value. Since passing by value creates a copy, the new (copied, function-scope) pointer will point to the same address as the original.

##### Share on other sites

Quote:
 Original post by zoner7Also, does the same process apply for pointers? If I pass a value to a function that asks for a pointer, will it have a pointer point to my value?

Same goes here. If the function asks for a pointer and you give it a pointer the function takes it as pointer.[/quote]

I meant to say what happens when I don't pass the function a pointer. I pass it a value instead of a pointer, even though it calls for a pointer. Will the function make a pointer to my value, just as it does with references in the previous scenario, or will I get a compile error?

##### Share on other sites
Yeah sorry, I was reading to fast. I have edited my post above, this wont compile at all.

##### Share on other sites
Quote:
Original post by Ariste
Quote:
 Original post by zoner7awesome. Just as I thought. Now what if i were to give the function a reference to inventory to begin with? Would the function make a reference to my reference? or would it simply use it as opposed to creating a new one?the former sounds sort of inefficient and pointless, but you never know?Also, does the same process apply for pointers? If I pass a value to a function that asks for a pointer, will it have a pointer point to my value?

I'm pretty sure that references-to-references are actually forbidden by the C++ standard. I might be crazy, but I think I read that somewhere. So, in answer to your first question: the function would just get a reference to your value, as normal.

As for pointers, think of them just like any other value-type. When you pass a pointer, the pointer is passed by value. Since passing by value creates a copy, the new (copied, function-scope) pointer will point to the same address as the original.

Would that imply that it is more efficient to pass by reference? If I actually give a function a reference, it does not need to make an extra variable. But if I pass any variable, whether it be a pointer or a value, to a function that calls for a pointer, it is still considered as passing by value and will still create a new pointer.

##### Share on other sites
Quote:
 foo(i); // <- wont even compilefoo(&i); // <- is the way to go here, note that now foo can change actual value of i

so this code essentially creates a pointer to a reference of a variable?

basically we have:

pointer -----> reference = value

##### Share on other sites
Quote:
 Original post by zoner7Would that imply that it is more efficient to pass by reference? If I actually give a function a reference, it does not need to make an extra variable. But if I pass any variable, whether it be a pointer or a value, to a function that calls for a pointer, it is still considered as passing by value and will still create a new pointer.

NO [smile]

MyClass mc;MyClass &rmc = mc;MyClass *pmc = &mc;// bad, needs to copy MyClass however big it is// call: foo(mc)void foo(MyClass mc);   // good, no need to copy, but is allowed to globally modify what you hand in as mc// call: foo(mc)  or  foo(rmc);void foo(MyClass &mc);   // good, no need to copy andguarantees not to globally modify what you hand in as mc// call: foo(mc)  or  foo(rmc);void foo(const MyClass &mc);// use a pointer as parameter, now it gets confusing a bit// call: foo(&mc)    // can globally change mc but not mc's address// call: foo(pmc)    // can globally change pmc but not pmc's addressvoid foo(MyClass *mc);   // use a pointer as const parameter// call: foo(&mc)    // can not globally change mc// call: foo(pmc)    // can not globally change pmcvoid foo(const MyClass *mc);   // and now a pointer to a pointer which is even more confusing at first// call: foo(&pmc);  // can globally change mc and its address alsovoid foo(MyClass **ppmc);

While the ** parameter seems to be weird at first it is quite common to let a function create instances for NULL pointers you hand in:

void foo(MyClass **pmc){   *pmc = new MyClass;}MyClass *pmc = 0;foo(&pm);

##### Share on other sites
Quote:
Original post by zoner7
Quote:
 foo(i); // <- wont even compilefoo(&i); // <- is the way to go here, note that now foo can change actual value of i

so this code essentially creates a pointer to a reference of a variable?

No.

int i = 0;      // is what you call a valueint &ri = i;    // is a reference to the value iint *pi = &i;   // is a pointer pointing to i's memory address

Thus foo(&i) calls the function and hands in a pointer pointing to i's memory address. I know its confusing at first because in C the & sign is used for different things. When put behind the type declaration it creates a reference to a value. When put after the = operator (which is implicitely present when you put a variable as parameter to a function) it access the memory address of the value it precedes thus effectively creating a pointer.

##### Share on other sites
thank you guys so much more the detailed and quite promptly given help. I understand the basics... the double ** might take a few more read throughs to digest. Thank you guys.

##### Share on other sites
Trust me, all C and C++ programmers had to struggle with this at first. Unfortunately some of them forgot that. [wink]

##### Share on other sites
Quote:
 Original post by zoner7If I actually give a function a reference

That's impossible. Whenever you write a reference variable in source code, it denotes the referent, not the reference it self.
int  i = 5;int& r = i;// From now on it does not matter if you write i or r// They both denote the same place in memory

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
627721
• Total Posts
2978804

• 10
• 9
• 21
• 14
• 12