Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can queue::pop return a value now?

Tags:

I know std::queue::pop() returns void. For two reasons:

  1. exception safety: something might throw after removing the element
  2. to be able to return the value by reference

Fine.

Now if I understand the new C++11 move semantics correctly, the second is no longer a valid argument.

So... the only thing preventing std::queue to have a pop-like function returning the value lies in the possibility that the move constructor throws?

I have a hard time thinking of situations where such a move constructor would throw. Who knows of an example?

I guess the same goes for std::stack::pop(), std::vector::pop_front(), std::vector::pop_back(), std::deque::pop_front(), std::deque::pop_back(), std::list::pop_front(), std::list::pop_back() and what not.

like image 485
Michel de Ruiter Avatar asked Feb 08 '12 10:02

Michel de Ruiter


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.

What does Pop do in queue?

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.

Does queue have pop?

queue::pop()pop() function is used to remove an element from the front of the queue(oldest element in the queue). This is an inbuilt function from C++ Standard Template Library(STL). This function belongs to the <queue> header file.


2 Answers

There aren't many cases where std::move() can throw in the standard library but there are cases. For example, if the container uses a stateful allocator, its children also use this allocator, but it won't be moved to a result: this would rather get a default constructed version of an allocator (if I remove correctly). Given that the allocators are stateful this means that the object can't be moved and thus the move construction fails with an exception. Why does this type then have a move constructor? Well, because it might be instantiated with non-stateful allocator in which case moving won't throw. In addition, once we move to user defined classes we have no idea under which condition moving them might throw.

like image 195
Dietmar Kühl Avatar answered Sep 17 '22 10:09

Dietmar Kühl


Using clever SFINAE techniques it would indeed be possible to have an atomic non-throwing pop_and_move() for just datatypes that implement no-throwing move or no-throwing copy.

There is even a noexcept() construct available to see if something might throw.

One of the new concepts in C++11 in particular that extends SFINAE is that if the body doesn't compile the function doesn't exist. Thus one could implement based on noexcept().

I would say for backward compatibility the function would need a new name, which therefore allows it to co-exist with the existing functionality of calling them separately, not breaking containers of types that do not have the semantics to allow it.

like image 20
CashCow Avatar answered Sep 19 '22 10:09

CashCow