pop_back()返回值?

为什么不pop_back()有一个返回值? 我已经谷歌search了这一点,发现它使它更有效率。 这是在标准中如此做的唯一原因吗?

我认为有一件事是相关的事实,复制最后一个对象的实例可能会引发exception。 当这样做的时候,你正在丢失你的对象,因为pop_back()确实从你的容器中删除了它。 更好的几行代码:

 std::vector<AnyClass> holds = {...} ; try { const AnyClass result = holds.pop_back(); // The copy Ctor throw here! } catch (...) { // Last value lost here. } 

效率几乎没有(或没有,真的)与它做。

这个devise是汤姆·嘉吉(Tom Cargill )在90年代发表的一篇重要论文的结果,当时引起了不less眉毛。 IIRC,嘉吉公司表示,devise一个exception安全的堆栈popupfunction是不可能的。

这是因为命令 – 查询分离原则 。

效率是一回事。 pop_back()不返回元素的另一个原因是exception安全。
如果pop()函数返回值,并且复制构造函数抛出exception,则可能无法保证容器与调用pop()之前的状态相同。

您可以在Herb Sutters书籍中find关于例外的更多信息。 我认为这个主题在这里介绍 。 但我不确定。

原因并不在于例外安全。 容器类可以用来存储任何types的对象。 如果函数在从容器中删除对象后返回对象,那么以exception安全的方式实现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()语句和返回对象的副本时。 没有保证返回expression式不会在元素被从容器中销毁之后抛出exception。

那么,有多less原因呢?

这样可以避免当您只想将其从容器中删除时,可能需要昂贵的复制对象。 C ++的哲学是不支付你不需要的东西。

为什么它会返回值? 您可以随时在popuppop_back之前随时访问该值 – 不需要使用pop_back来提供此function。