Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could stack pop operation return the value safely in C++11

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?

like image 401
Honf Avatar asked Dec 25 '13 19:12

Honf


People also ask

Does stack POP return value?

The function is used only for the removal of elements from the stack and has no return value.

What does pop return in C?

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.

What does pop return if stack is empty?

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.

What is the use of pop in stack?

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


1 Answers

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;
}
like image 68
Honf Avatar answered Sep 20 '22 16:09

Honf