为什么不std :: queue :: pop返回值。

我经历了这个页面,但我无法得到相同的理由。 那里有提到

“它是更明智的,它根本不返回任何价值,并要求客户使用前()检查队列前面的值”

但是从front()检查一个元素也需要该元素在左值被复制。 例如在这个代码段

std::queue<int> myqueue; int myint; int result; std::cin >> myint; myqueue.push (myint); 

/ *这里临时将在RHS上创build,这将被分配给结果,并且如果通过引用返回,则结果将在popup操作后被渲染为无效* /

 result = myqueue.front(); //result. std::cout << ' ' << result; myqueue.pop(); 

在第五行cout对象首先创buildmyqueue.front()的副本,然后将其分配给结果。 所以,差异是什么,popupfunction可以做同样的事情。

所以,差异是什么,popupfunction可以做同样的事情。

它确实可以做同样的事情。 之所以不这样做,是因为返回popup元素的pop在exception情况下(不得不依靠值返回,从而创build副本)是不安全的。

考虑这种情况(用一个天真的/stream行的stream行实现来说明我的观点):

 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 } 

如果T的拷贝构造函数在返回时抛出,你已经改变了队列的状态(我的天真实现中的top_position ),并且元素从队列中被移除(而不是返回)。 对于所有的意图和目的(无论您如何捕获客户端代码中的exception),队列顶部的元素都会丢失。

这个实现在不需要popup的值的情况下也是低效的(即它创build了一个没有人使用的元素的副本)。

这可以通过两个单独的操作( void popconst T& front() )安全有效地实现。

您链接的页面可以解答您的问题。

引用相关的全部内容:

有人可能会问为什么pop()返回void而不是value_type。 也就是说,为什么必须使用front()和pop()来检查和删除队列前面的元素,而不是在单个成员函数中组合这两个元素? 事实上,这个devise有一个很好的理由。 如果pop()返回前面的元素,它将不得不返回值而不是引用:通过引用返回将创build一个悬挂指针。 然而,按值返回是低效的:至less涉及一个冗余拷贝构造函数调用。 由于pop()不可能以有效和正确的方式返回一个值,所以它根本不返回任何值,并要求客户使用front()来检查值队列的前面。

C ++的devise是考虑到效率的,而不是程序员必须编写的代码行数。

pop不能返回被删除的值的引用,因为它正在从数据结构中删除,那么引用是指什么呢? 它可以返回值,但如果stream行的结果没有存储在任何地方呢? 然后浪费时间复制这个值。

在目前的实施中,这是有效的:

 int &result = myqueue.front(); std::cout << result; myqueue.pop(); 

如果pop会返回一个引用,像这样:

 value_type& pop(); 

然后下面的代码可能会崩溃,因为引用无效:

 int &result = myqueue.pop(); std::cout << result; 

另一方面,如果它会直接返回一个值:

 value_type pop(); 

那么你需要为这个代码做一个副本来工作,效率较低:

 int result = myqueue.pop(); std::cout << result; 

你完全可以这样做:

 std::cout << ' ' << myqueue.front(); 

或者,如果您想要variables中的值,请使用引用:

 const auto &result = myqueue.front(); if (result > whatever) do_whatever(); std::cout << ' ' << result; 

除此之外:“更明智”的措词是“我们研究使用模式并发现更多需要分裂”的主观forms。 (请放心:C ++语言不会轻易演变…)

我认为最好的解决办法是添加类似的东西

 std::queue::pop_and_store(value_type& value); 

价值将收到popup的价值。

优点是可以使用移动赋值操作符来实现,而使用front + pop将会复制。