Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't std::queue::pop return value.?

Tags:

c++

stl

People also ask

Does queue pop return value?

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.

How do you pop a queue in C++?

C++ Queue Library - pop() Function The C++ function std::queue::pop() removes front element of the queue and reduces size of the queue by one. This member function effectively calls the pop_front member function of the underlying container.

What does pop return in C++?

pop() does not return any value. Because pop() is void function.


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()).


The page you have linked to answers your question.

To quote the whole section relevant:

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.


pop cannot return a reference to the value that is removed, as it is being removed from the data structure, so what should the reference refer to? It could return by value, but what if the result of pop is not stored anywhere? Then time is wasted copying the value unnecessarily.


With the current implementation, this is valid:

int &result = myqueue.front();
std::cout << result;
myqueue.pop();

If pop would return a reference, like this:

value_type& pop();

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;