为什么pop_back()
没有返回值?我用Google搜索了这一点,发现它使它更有效率。这是在标准中实现这一目标的唯一原因吗?
答案 0 :(得分:57)
效率很少(或没有,真的)与它有关。
这个设计是90年代出版的an important paper by Tom Cargill的结果,当时引起了不少人的关注。 IIRC,Cargill在其中展示了设计异常安全堆栈弹出功能是不可能的。
答案 1 :(得分:51)
我认为复制最后一个对象的实例可能会引发异常。这样做时,你丢失了你的对象,因为pop_back()确实从容器中删除了它。使用几行代码更好:
std::vector<AnyClass> holds = {...} ;
try {
const AnyClass result = holds.pop_back(); // The copy Ctor throw here!
} catch (...)
{
// Last value lost here.
}
答案 2 :(得分:15)
答案 3 :(得分:6)
效率是一回事。 pop_back()
不返回元素的另一个原因是异常安全
如果pop()
函数返回了值,并且复制构造函数抛出了异常,则可能无法保证容器与调用pop()
之前的状态相同。
您可以在Herb Sutters书籍中找到有关例外情况的更多信息。我认为这个主题涉及here。但我不确定。
答案 4 :(得分:4)
原因不是例外安全的效率。容器类可用于存储任何类型的对象。如果函数在从容器中删除对象后返回对象,则不可能以异常安全的方式实现pop_back(),因为返回对象的值涉及复制构造。
这是GNU C ++标准库中vector :: pop_back()的实际实现:
void
pop_back()
{
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
}
如果它最后返回最后一个元素,它会是什么样子:
value_type
pop_back()
{
value_type save = back();
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
return save;
}
这涉及两个复制结构,在save = back()
语句和返回对象的副本时。无法保证返回表达式在从容器中销毁元素后不会抛出异常。
答案 5 :(得分:2)
那么,有多少原因?
当您只想将其从容器中删除时,这可以避免对象的潜在昂贵复制。 C ++的理念是不为你不需要的东西买单。
答案 6 :(得分:-1)
为什么会返回值?您可以随时在弹出之前随时访问该值 - pop_back
无需提供此功能。