C++ STL 堆栈问题 : Why does pop() not throw an exception if the stack is empty?

标签 c++ exception stl stack

如果堆栈为空且没有可弹出的内容,为什么 std::stack::pop() 不抛出异常?

(我正在为我自己的代码设计一个专门的堆栈,并且想知道这种方法(需要手动检查堆栈是否为空)与抛出异常之间的权衡。

我的猜测是,尽管 C++ 支持异常处理,但它的运行时开销很小,因此,为了获得最佳性能,决定不在 std::stack::pop 中抛出异常)。

最佳答案

我认为 pop() 不必抛出异常的原因与效率或性能无关,而是与异常有关。

正如所争论的 elsewhere :

  1. SGI explanation: http://www.sgi.com/tech/stl/stack.html One might wonder why pop() returns void, instead of value_type. That is, why must one use top() and pop() to examine and remove the top element, instead of combining the two in a single member function? In fact, there is a good reason for this design. If pop() returned the top 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 top() to inspect the value at the top of the stack.

  2. std::stack < T > is a template. If pop() returned the top element, it would have to return by value rather than by reference as per the of above explanation. That means, at the caller side it must be copied in an another T type of object. That involves a copy constructor or copy assignment operator call. What if this type T is sophisticated enough and it throws an exception during copy construction or copy assignment? In that case, the rvalue, i.e. the stack top (returned by value) is simply lost and there is no other way to retrieve it from the stack as the stack's pop operation is successfully completed!

一旦我们得出结论 pop 应该返回它弹出的元素,因此它的接口(interface)被固定为 void pop(),它 - 这是我的意见 - 不'不再规定在空堆栈上调用 pop() 时会发生什么。

请注意,标准要求 !empty()作为调用 pop() 的前提条件。

UncleBens(在评论中)当然有一点,即在运行时不检查先决条件(C++ std AFAIK 从未规定过)对它有一定的性能气味。但是,引用原始问题的一部分:(强调我的)

(I'm designing a specialized Stack for my own code and would like to know the tradeoffs with this approach (which requires one to manually check if the stack is empty) vs. throwing an exception.

我会争辩说,pop() 不返回任何内容的事实使问题变得毫无意义。它(恕我直言)根本没有意义强制 pop() 验证堆栈是否为空,当我们真的没有从中得到任何东西时(即如果堆栈为空 pop() 可以只是一个 noop ,(诚然)Std 也没有规定)。

我认为人们可以问为什么 top() 不抛出异常可以问为什么 pop() 不返回顶部元素。如果 pop 不返回任何内容,则抛出异常没有意义(在 C++ 世界中)——声称它不会抛出异常“因为异常的运行时成本”,例如其他答案似乎暗示 - 恕我直言 - 没有捕获重点。

关于C++ STL 堆栈问题 : Why does pop() not throw an exception if the stack is empty?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4892108/

相关文章:

c# - 调试器不会因异步方法中的异常而中断/停止

ios - Mac OS X 上的 CGContextShowText 异常。iOS 上正常

c++ - 声明 std::map 常量

c++ - 你知道学习运算符优先级和结合性的心理装置或技巧吗?

java - 缺少重要参数/依赖项时抛出什么异常?

c++ - 将指向堆栈变量的指针传递给 realloc() 是否有效?

c++ - 带有 char16_t 或 char32_t 的 Visual Studio C++ 2015 std::codecvt

c++ - 为什么 C++ 不需要 "new"语句来初始化 std::vector?

c++ - C++11 中 std::less 的模板特化,使用模板

c++ - 检查骑士在两点之间移动是否有效