为什么不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 pop
和const 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将会复制。