为什么没有pop_back()
返回值?我用Google搜索了这一点,发现它使它更有效率.这是在标准中做到这一点的唯一原因吗?
sbi*_*sbi 58
效率几乎没有(或者没有,真的)与它有关.
这个设计是汤姆·卡吉尔(Tom Cargill)在90年代出版的一篇重要论文的结果,当时引起了不少人的关注.IIRC,Cargill在其中展示了设计异常安全堆栈弹出功能是不可能的.
yve*_*mes 52
我认为有一些事情与复制最后一个对象的实例可能会引发异常有关.这样做时,你丢失了你的对象,因为pop_back()确实从容器中删除了它.使用几行代码更好:
std::vector<AnyClass> holds = {...} ;
try {
const AnyClass result = holds.pop_back(); // The copy Ctor throw here!
} catch (...)
{
// Last value lost here.
}
Run Code Online (Sandbox Code Playgroud)
那么,有多少个理由呢?
当您只想从容器中删除对象时,这可以避免潜在的昂贵的对象复制。C++ 的理念是不为不需要的东西付费。
原因与其说是效率不如说是异常安全。容器类可用于存储任何类型的对象。如果函数在从容器中删除对象后返回对象,则不可能以异常安全的方式实现 pop_back(),因为返回对象的值涉及复制构造。
这是 GNU C++ 标准库中 vector::pop_back() 的实际实现:
void
pop_back()
{
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
}
Run Code Online (Sandbox Code Playgroud)
如果它最终返回最后一个元素,它会是什么样子:
value_type
pop_back()
{
value_type save = back();
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
return save;
}
Run Code Online (Sandbox Code Playgroud)
这涉及两个复制构造,在save = back()
语句中和在返回对象的副本时。无法保证在元素从容器中销毁后返回表达式不会抛出异常。