Reputation: 395
I'm playing with some examples to decide whether it is safe to use the reference to the front of the queue when I know it is going to be popped later.
queue<int> q;
q.push(5);
q.push(2);
int & a = q.front(); // a = 5 now
q.pop();
q.push(123);
cout << a << "\n"; // a = 5 now
This example makes it look like it is safe.
queue<int> q;
q.push(5);
int & a = q.front(); // a = 5 now
q.pop();
q.push(123);
cout << a << "\n"; // a = 123 now
This example makes me realize I probably have to make a copy of the front element instead of using a reference. However, I do not understand the behavior discrepancy between the two examples. Shouldn't the second example variable "a" also be 5? Can someone explain it to me?
Upvotes: 1
Views: 1854
Reputation: 73186
All standard references below refers to N4659: March 2017 post-Kona working draft/C++17 DIS.
As governed by [deque.modifiers]/4 [emphasis mine]:
iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_front(); void pop_back();
Effects: An erase operation that erases the last element of a deque invalidates only the past-the-end iterator and all iterators and references to the erased elements. An erase operation that erases the first element of a deque but not the last element invalidates only iterators and references to the erased elements. An erase operation that erases neither the first element nor the last element of a deque invalidates the past-the-end iterator and all iterators and references to all the elements of the deque. [ Note:
pop_front
andpop_back
are erase operations. — end note ]
The effects of invoking pop()
on a std::queue
object is as if invoking pop_front()
on a std::deque
object. Thus, storing a reference to the front()
of a std::queue
object, say stored as ref_front
, followed by invocation of pop()
on the queue object invalidates the ref_front
reference.
queue<int> q;
q.push(5);
int & a = q.front();
q.pop(); // invalidates reference 'a'
// ... reading 'a' invokes undefined behaviour
Thus, both your examples invokes undefined behaviour, demons may fly out of your nose and any kind of analysis of your program beyond this point will be a fruitless exercise.
Upvotes: 3