我浏览了这个页面,但我无法得到同样的理由.在那里提到了
"它根本不返回任何值并要求客户端使用front()来检查队列前面的值更为明智"
但是检查front()中的元素也需要将该元素复制到左值.例如,在此代码段中
std::queue<int> myqueue;
int myint;
int result;
std::cin >> myint;
myqueue.push (myint);
Run Code Online (Sandbox Code Playgroud)
/*这里临时将在RHS上创建,它将被分配给结果,如果通过引用返回,则在弹出操作后结果将变为无效*/
result = myqueue.front(); //result.
std::cout << ' ' << result;
myqueue.pop();
Run Code Online (Sandbox Code Playgroud)
在第五行cout对象首先创建myqueue.front()的副本然后将其分配给结果.那么,最重要的是,pop功能可以做同样的事情.
utn*_*tim 92
那么,最重要的是,pop功能可以做同样的事情.
它确实可以做同样的事情.它没有的原因是因为返回弹出元素的pop在出现异常时是不安全的(必须按值返回并因此创建副本).
考虑一下这个场景(用一个天真的/编造的pop实现来说明我的观点):
template<class T>
class queue {
T* elements;
std::size_t top_position;
// stuff here
T pop()
{
auto x = elements[top_position];
// TODO: call destructor for elements[top_position] here
--top_position; // alter queue state here
return x; // calls T(const T&) which may throw
}
Run Code Online (Sandbox Code Playgroud)
如果T的复制构造函数在返回时抛出,则您已经更改了队列的状态(top_position
在我的天真实现中),并且元素将从队列中删除(并且不会返回).对于所有意图和目的(无论您如何捕获客户端代码中的异常),队列顶部的元素都将丢失.
当您不需要弹出值时(即,它会创建一个没人会使用的元素的副本),此实现也是低效的.
这可以通过两个单独的操作(void pop
和const T& front()
)安全有效地实现.
小智 32
您链接的页面会回答您的问题.
引用相关的整个部分:
有人可能想知道为什么pop()返回void而不是value_type.也就是说,为什么必须使用front()和pop()来检查和删除队列前面的元素,而不是将它们组合在一个成员函数中?事实上,这种设计有充分的理由.如果pop()返回前面的元素,它将不得不按值而不是通过引用返回:按引用返回将创建一个悬空指针.然而,按值返回是低效的:它涉及至少一个冗余复制构造函数调用.因为pop()不可能以高效和正确的方式返回值,所以更不明智地返回任何值并要求客户端使用front()来检查值队列的前面.
在编程人员必须编写的代码行数上,C++的设计考虑了效率.
pop不能返回对被删除的值的引用,因为它正从数据结构中删除,那么引用应该引用什么?它可以按值返回,但是如果pop的结果没有存储在任何地方呢?然后浪费时间不必要地复制价值.
归档时间: |
|
查看次数: |
44610 次 |
最近记录: |