Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I went through this
page
but I am not able to get the reason for the same . There it is mentioned that
"it is more sensible for it to return no value at all and to require
clients to use front() to inspect the value at the front of the queue"
But inspecting an element from front() also required that element to be copied in lvalue. For example in this code segment
std::queue<int> myqueue;
int myint;
int result;
std::cin >> myint;
myqueue.push (myint);
/* here temporary will be created on RHS which will be assigned to
result, and in case if returns by reference then result will be
rendered invalid after pop operation */
result = myqueue.front(); //result.
std::cout << ' ' << result;
myqueue.pop();
on fifth line cout object first creates a copy of myqueue.front() then assigns that to result. So, whats the difference, pop function could have done the same thing.
–
–
–
–
It could indeed have done the same thing. The reason it didn't, is because a pop that returned the popped element is unsafe in the presence of exceptions (having to return by value and thus creating a copy).
Consider this scenario (with a naive/made up pop implementation, to ilustrate my point):
template<class T>
class queue {
T* elements;
std::size_t top_position;
// stuff here
T pop()
auto x = elements[top_position];
// TODO: call destructor for elements[top_position] here
--top_position; // alter queue state here
return x; // calls T(const T&) which may throw
If the copy constructor of T throws on return, you have already altered the state of the queue (top_position
in my naive implementation) and the element is removed from the queue (and not returned). For all intents and purposes (no matter how you catch the exception in client code) the element at the top of the queue is lost.
This implementation is also inefficient in the case when you do not need the popped value (i.e. it creates a copy of the element that nobody will use).
This can be implemented safely and efficiently, with two separate operations (void pop
and const T& front()
).
–
–
–
–
–
One might wonder why pop() returns void, instead of value_type. That is, why must one use front() and pop() to examine and remove the element at the front of the queue, instead of combining the two in a single member function? In fact, there is a good reason for this design. If pop() returned the front element, it would have to return by value rather than by reference: return by reference would create a dangling pointer. Return by value, however, is inefficient: it involves at least one redundant copy constructor call. Since it is impossible for pop() to return a value in such a way as to be both efficient and correct, it is more sensible for it to return no value at all and to require clients to use front() to inspect the value at the front of the queue.
C++ is designed with efficiency in mind, over the number of lines of code the programmer has to write.
–
–
–
–
–
–
Then the following code could crash, since the reference is not valid anymore:
int &result = myqueue.pop();
std::cout << result;
On the other hand, if it would return a value directly:
value_type pop();
Then you would need to do a copy for this code to work, which is less efficient:
int result = myqueue.pop();
std::cout << result;
Or, if you want the value in a variable, use a reference:
const auto &result = myqueue.front();
if (result > whatever) do_whatever();
std::cout << ' ' << result;
Next to that: the wording 'more sensible' is a subjective form of 'we looked into usage patterns and found more need for a split'. (Rest assured: the C++ language is not evolving lightly...)
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.