C++ pop_back() 返回值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12600330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
pop_back() return value?
提问by Parvinder Singh
Why doesn't pop_back()
have a return value? I have Googled regarding this and found out that it makes it more efficient. Is this the only reason for making it so in the standard?
为什么没有pop_back()
返回值?我在谷歌上搜索过这个,发现它使它更有效率。这是在标准中做到这一点的唯一原因吗?
采纳答案by yves Baumes
I think there is something related to the fact that copying an instance of the last object could throw an exception. When doing so, you're losing your object, since pop_back() did remove it from your container. Better with a few lines of code:
我认为有一些与复制最后一个对象的实例可能引发异常的事实有关。这样做时,您将丢失对象,因为 pop_back() 确实将其从容器中删除。用几行代码更好:
std::vector<AnyClass> holds = {...} ;
try {
const AnyClass result = holds.pop_back(); // The copy Ctor throw here!
} catch (...)
{
// Last value lost here.
}
回答by sbi
Efficiency has little (or nothing, really) to do with it.
效率与它几乎没有(或根本没有)关系。
This design is the outcome of an important paper by Tom Cargill, published in the 90s, that raised quite a few eyebrows back then. IIRC, in it Cargill showed that it is impossible to design an exception safe stack pop function.
这个设计是Tom Cargill在 90 年代发表的一篇重要论文的成果,当时引起了很多人的注意。IIRC,其中嘉吉表明不可能设计异常安全的堆栈弹出函数。
回答by Abyx
It's because of the Command-query separation principle.
这是因为命令查询分离原则。
回答by mkaes
Efficiency is one thing. Another reason for pop_back()
not returning an element is exception safety.
If the pop()
function returned the value, and an exception is thrown by the copy constructor, you may not be able to guarantee that the container is in the same state as it was before calling pop()
.
效率是一回事。pop_back()
不返回元素的另一个原因是异常安全。
如果pop()
函数返回值,并且复制构造函数抛出异常,则您可能无法保证容器处于调用 之前的状态pop()
。
You can find more infos in Herb Sutters books about exceptions. I think this topic is covered here. But I am not sure.
您可以在 Herb Sutters 书籍中找到有关异常的更多信息。我想这个话题在这里涵盖。但我不确定。
回答by Seppo Enarvi
The reason is not so much efficiency as exception safety. The container class can be used to store any kind of objects. It would be impossible to implement pop_back() in an exception safe manner if the function would return the object after deleting it from the container, because returning the value of the object involves copy construction.
原因与其说是效率不如说是异常安全。容器类可用于存储任何类型的对象。如果函数在从容器中删除对象后返回对象,则不可能以异常安全的方式实现 pop_back(),因为返回对象的值涉及复制构造。
This is the actual implementation of vector::pop_back() in GNU C++ standard library:
这是 GNU C++ 标准库中 vector::pop_back() 的实际实现:
void
pop_back()
{
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
}
This is what it would look like should it return the last element in the end:
如果它最终返回最后一个元素,它会是什么样子:
value_type
pop_back()
{
value_type save = back();
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
return save;
}
This involves two copy constructions, at the save = back()
statement and when returning a copy of the object. There are no guarantees that the return expression won't throw an exception after the element has been destroyed from the container.
这涉及两个复制构造,在save = back()
语句中和在返回对象的副本时。无法保证在元素从容器中销毁后返回表达式不会抛出异常。
回答by Zdeslav Vojkovic
Well, how many reasons there have to be?
那么,必须有多少理由?
This avoids potentially expensive copying of the object when you just want to remove it from the container. C++ has the philosophy of not paying for what you don't need.
当您只想从容器中删除对象时,这避免了可能昂贵的对象复制。C++ 的理念是不为你不需要的东西付费。
回答by Puppy
Why would it return the value? You can always access the value at any time prior to popping it off- there is no need for pop_back
to provide this functionality.
为什么它会返回值?您始终可以在弹出之前随时访问该值 - 无需pop_back
提供此功能。