Exception safety with std::stack

What happens if an exception is thrown while I'm modifying a std::stack? Is it exception-safe?

Yes, std::stack is designed to be exception-safe. The C++ Standard Library guarantees that all operations on std::stack either succeed completely or have no effect if an exception is thrown. This is known as the strong exception guarantee.

Let's look at what this means for some common operations:

  1. push() or emplace(): If an exception is thrown during the insertion of a new element (either due to a copy/move operation or due to the container running out of memory), the stack remains unchanged. The element is not added, and any elements previously in the stack are still present and unchanged.
  2. pop(): If an exception is thrown during the removal of the top element, the element is still removed. No elements are left in an invalid or unspecified state.

Here's an example:

#include <iostream>
#include <stack>

class MyClass {
 public:
  MyClass(int id) : id(id) {
    if (id == 4) {
      throw std::runtime_error(
        "Cannot copy MyClass with id 2");
    }
  }

  int id;
};

int main() {
  std::stack<MyClass> s;

  try {
    s.emplace(1);
    s.emplace(2);
    s.emplace(3);
    s.emplace(4);  // this will throw
  } catch (...) {
    std::cout << "Exception caught! stack size: "
      << s.size() << '\n';
  }

  // The stack is still in a valid state
  while (!s.empty()) {
    std::cout << s.top().id << ' ';
    s.pop();
  }
}
Exception caught! stack size: 3
3 2 1

In this code, when the stack tries to copy an instance of MyClass with id 2, an exception is thrown. However, the stack remains in a valid state. The element with id 1, which was previously inserted successfully, is still present and can be accessed normally.

The strong exception guarantee is an important property that allows you to write robust, error-resistant code. It means that if an exception is thrown, you don't need to worry about your stack being left in an inconsistent or corrupted state.

Introduction to Stacks using std::stack

An introduction to the stack data structure, and the standard library implementation - std::stack

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

When to use std::stack vs std::vector?
In what situations would I choose to use a std::stack instead of a std::vector in C++? They seem to have similar functionality.
Changing the underlying container of std::stack
What are some reasons I might want to change std::stack's underlying container to something other than std::deque?
Iterating over a std::stack
How can I iterate over all the elements in a std::stack? There don't seem to be any obvious methods for this.
Thread safety with std::stack
Is std::stack thread-safe? Can I safely access a stack concurrently from multiple threads?
Performance considerations with std::stack
What are some performance considerations to keep in mind when using std::stack?
std::stack::emplace vs std::stack::push
What's the difference between std::stack::emplace and std::stack::push? When should I use one over the other?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant