template<class T>
T Stack<T>::pop()
{
if (vused_ == 0)
{
throw "Popping empty stack";
}
else
{
T result = v_[used_ - 1];
--vused_;
return result;
}
}
我没有完全理解,或者更确切地说,我一个都没有理解,但据说这段代码不起作用,因为它按值返回,我猜他指的是结果,那调用复制构造函数,我什至不知道这怎么可能。谁能解释一下?
最佳答案
与问题示例中的代码不同,std::stack<T>::pop
不返回值。
那是因为如果项目类型需要被复制,并且复制抛出异常,那么你的操作失败已经改变了对象的状态,没有办法重新建立原始状态。
即返回值- pop
不提供 strong exception guarantee (要么成功,要么没有变化)。
同样,至少可以说,抛出文字字符串是非常规的。
因此,虽然代码本身没有任何错误(模可能的输入错误,例如 vused_
与 v_
等),但它在保证方面很薄弱,而且非常规,可能会导致其他地方的异常处理中出现错误.
另一种观点是,非值(value)返回pop
的 std::stack
不切实际,导致客户端代码不必要地冗长。
对于使用堆栈对象,我更喜欢返回值 pop
.
但它不是非此即彼:返回值的便捷方法 popped
可以根据 pop
轻松定义(状态变化)和top
(检查)。然后,此便捷方法具有较弱的异常保证。但是客户端代码程序员可以选择。 :-)
现有设计中的一个改进是支持可移动物体,即替换
return result;
与
return move( result );
稍微帮助一下编译器。
↑ 更正:
实际上,上面删除的文本具有与预期相反的效果,即它抑制了 RVO(保证调用构造函数)。不知何故,我的想法在这里被颠倒了。但通常不要使用 move
在 return
上expression 只是一个非参数自动变量的名字,因为默认是optimization,加上move
不能改善事物,但可以抑制 RVO 优化。
关于c++ - 按值返回调用复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22412461/