So, it would seem that the segregation of .top and .pop in stack is no longer needed to be so strict in C++11.
Maybe I am missing something, but the problem in C++03 and previous was that if .pop were to return a value, there was a danger the copy operation could throw an exception during the element copy. Example (code sample taken from here):
template <class T>
// T must have default ctor and copy assignment
class Stack
{
public:
Stack();
~Stack();
Stack(const Stack&);
Stack& operator=(const Stack&);
unsigned Count(); // returns # of T's in the stack
void Push(const T&);
T Pop(); // if empty, returns default-
// constructed T
T Top(); // For backwards compatibility
//
private:
T* v_; // pointer to a memory area big
// enough for 'vsize_' T objects
unsigned vsize_; // the size of the 'v_' area
unsigned vused_; // the number of T's actually
// used in the 'v_' area
};
If you are to do this:
int main(){
Stack<vector<double>> stack;
fill_stack(stack); //fill stack with huge vectors
stack.pop(); //danger of exception being throw from low memory
}
In C++11 this problem goes entirely away since the element can be moved from the stack, entirely eliminating the exception safety concern. That is under the presumption that the element is movable and that the move operation will not throw.
So, my question boils down to, is there a real concert to safety exception concern if .pop were to return the element via move semantics?
The function is used only for the removal of elements from the stack and has no return value.
Write a pop() function that is the inverse of push(). The pop() function takes a non-empty list, deletes the head node, and returns the head node's data.
Return Value: This method returns the element present at the top of the stack and then removes it. Exceptions: The method throws EmptyStackException is thrown if the stack is empty.
The pop() function is used to remove or 'pop' an element from the top of the stack(newest or the topmost element in the stack).
After a few pointer from DyP, this code should do the trick I'm asking for in OP.
Since top
returns by reference, it can be safely moved from and then immediately pop
-ed.
The helper function checks that the preconditions are meet (must be move constructible) and hopefully is a nothrow operation :)
template<class T>
T pull_top(std::stack<T>& x) noexcept(std::is_nothrow_move_constructible<T>::value)
{
static_assert(std::is_move_constructible<T>::value, "pull_top requires the type to be move constructible");
T val = std::move(x.top());
x.pop();
return val;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With