Mar*_* Ba 14
我认为pop()不必抛出异常的原因与效率或性能无关,而是与 - 例外.
正如其他地方所说:
SGI解释:http://www.sgi.com/tech/stl/stack.html 人们可能想知道为什么pop()返回void而不是value_type.也就是说,为什么必须使用top()和pop()来检查和删除顶部元素,而不是将两者组合在一个成员函数中?事实上,这种设计有充分的理由.如果pop()返回顶部元素,则必须按值而不是按引用返回:按引用返回将创建一个悬空指针.然而,按值返回是低效的:它涉及至少一个冗余复制构造函数调用.由于pop()不可能以高效和正确的方式返回值,因此更不明智地返回任何值并要求客户端使用top()来检查值堆栈的顶部.
std :: stack <T>是一个模板.如果pop()返回顶部元素,则必须按值返回,而不是按照上述说明返回.这意味着,在调用者端,它必须被复制到另一种T类型的对象中.这涉及复制构造函数或复制赋值操作符调用.如果这种类型T足够复杂并且在复制构造或复制分配期间抛出异常怎么办?在这种情况下,rvalue,即堆栈顶部(由值返回)简单地丢失,并且没有其他方法可以从堆栈中检索它,因为堆栈的弹出操作已成功完成!
一旦我们的结论是流行应该不会返回它弹出的元素,因此它的接口是固定的void pop()
,它-这是我的观点-没有任何意义了规定时pop()方法被称为空栈上发生了什么.
请注意,标准要求!empty()
作为调用pop()的前提条件.
UncleBens(在评论中)肯定有一点,即不在运行时检查前置条件(C++ std AFAIK从未规定)具有一定的性能气味.但是,引用原始问题的一部分:(强调我的)
(我正在为自己的代码设计一个专用的堆栈,并想知道这种方法的权衡(需要人们手动检查堆栈是否为空)而不是抛出异常.
我会争辩说,pop()
不返回任何东西的事实使得这个问题没有实际意义.它(恕我直言)根本没有意义迫使pop()验证堆栈是否为空,当我们真的没有从它得到任何回报时(即如果堆栈是空的pop()可以简单地是一个noop ,(诚然)也没有由Std规定).
我想可以问为什么top()
不抛出异常或者可以问为什么pop()
不返回顶部元素.如果pop
没有返回任何东西,抛出一个异常没有意义(在C++世界中) - 声称它不会抛出异常"因为异常的运行时成本",就像其他答案似乎意味着 - 恕我直言 - 错过了重点.
你是对的.C++标准始终优先考虑性能和安全性.但是可能存在包括调试范围检查的STL实现.
与C++中的几乎所有功能一样,它们是围绕您不为不使用的内容付费的概念而设计的.并非所有环境都支持异常,传统上,尤其是游戏开发.
因此,如果使用std :: stack,强制使用异常将失败其中一个设计指南.即使禁用了异常,您也希望能够使用堆栈.
归档时间: |
|
查看次数: |
9651 次 |
最近记录: |