0

I am a bit unsure of how to use the values returned by front() function from std::queue library. On the website cplusplus.com , it says the function returns a reference. However, when I looked at the actual usages, it seems like the function is used directly to get the value.

For example, by following these steps

std::queue<int> myqueue;
myqueue.push(30);

The return value should be stored as follow:

int &some_number  = myqueue.front();

So how come this is possible:

std::cout << "myqueue.front() returns " << myqueue.front() 
//myqueue.front() returns 30

If it's returning reference to value, doesn't that mean it's returning the location where the value is stored at, and not the value itself? So how come printing the location prints out the value not the address of the integer.

Also, following this logic, does it mean these also work?

Scenario 1

std::queue<int> myqueue;
myqueue.push(30);
int new_number = myqueue.front();

new_number's value will be 30

Scenario 2 - (someStruct is a defined struct)

std::queue<someStruct*> myqueue;
myqueue.push(someStruct* abcPtr); \\abcPtr has been initialized 
someStruct* edfPtr= myqueue.front();

edfPtr will be pointing to the same location abcPtr is pointing too.

if so, then what's the point of passing the value returned by std::queue::front as reference. Does anyone know the logic behind the usage?

user59290
  • 138
  • 1
  • 10
  • 4
    Don't think of a reference as a pointer, think of it as an *alias* or *synonym*. See this: https://stackoverflow.com/q/620604/10077 – Fred Larson Jan 29 '18 at 17:26
  • I see. So does that mean doing this `&some_int =...` won't do anything to change the location `some_int` is pointing to, but only its value? – user59290 Jan 29 '18 at 17:52

2 Answers2

1

It does return a reference, but (just like other cases) if you assign from the reference to a normal object of that type, the object referred to by the reference is assigned.

int a = 1;
int &ra = a; // reference to a

int b = ra;  // initializes `b` to the value referred to by `ra`--1 in this case.

In the specific case of front(), if the value you've stored is something large, you may want to avoid creating an extra copy of it. In this case, you can use the reference directly, or use it to initialize another reference to get an alias to the value that's in the queue, so you can use it without creating a copy.

class something_big {
    // lots of data here
};

std::queue<something_big> foo;

something_big bar = foo.front(); // copies entire item from front of queue into bar

something_big &baz = foo.front(); // no copy; just access item in queue
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • does that mean doing this `&some_int =3` won't do anything to change the location of `some_int`, but only its value? And doing this `&some_ptr =another_ptr` (assign value to reference of pointer) will only change the location that `some_ptr` is pointing to? Which is also equivalent to writing `some_ptr =another_ptr`? – user59290 Jan 29 '18 at 18:20
0

The logic of returning a reference is to avoid a copy unless necessary. If the queue, instead of having an integer or a pointer, contained something heavier, like a large struct, or a large vector.

int math_on_large_vector(const std::vector<int>& data) {
    // ...
}

std::queue<std::vector<int>> myqueue;
myqueue.emplace(std::vector<int>(10000, 0));
math_on_large_vector(myqueue.front()) // Doesn't copy the entire vector

If you want to copy the object at the front of the queue, just call a copy constructor or assignment.

std::vector<int> local_copy(my_queue.front());

or

local_copy = my_queue.front();

This doesn't really matter for something like int or a pointer, but it does for something that is expensive to copy.

dfreese
  • 378
  • 1
  • 10