У меня есть следующая проблема с двоичным деревом:
....
template class BinaryTree { private: template struct Node { T value; Node* left; Node* right; }; private: Node* root;
std::stack<Node<T>const *> stack;
stack.push(root);
while(false == stack.empty())
{
Node<T>* node = stack.pop();
this->visited(node->value);
и после этого, когда я попытался реализовать предварительный поиск дыхания: template class BinaryTree {private: template struct Node {T value; Node* left; Узел * слева; Node* right; Узел * справа; }; }; private: Node * root;
std::stack<Node<T>const *> stack;
stack.push(root);
while(false == stack.empty())
{
Node<T>* node = stack.pop();
this->visited(node->value);
Я получил ошибку:
Ошибка 4 ошибки C2440: 'initializing': не может преобразовать из 'void' в 'BinaryTree :: Node *' c:\users\stephan\documents\visual studio 2012\projects\graphs\binarytree\binarytree.cpp 152 1 BinaryTree
Проблема здесь:
Node<T>* node = stack.pop();
pop()
удаляет элемент и возвращает void
. Используйте top()
заранее.
Node<T>* node = stack.top();
stack.pop();
В оригинальной документации STL объясняются причины этого дизайна:
Интересно, почему pop() возвращает void вместо value_type. То есть, почему нужно использовать top() и pop() для проверки и удаления верхнего элемента вместо объединения двух в одну функцию-член? На самом деле, есть веская причина для этого дизайна. Если pop() вернул верхний элемент, ему пришлось бы возвращать по значению, а не по ссылке: return by reference создавал бы висячий указатель. Однако возврат по значению неэффективен: он включает по крайней мере один избыточный вызов конструктора копии. Так как невозможно, чтобы pop() возвращало значение таким образом, чтобы быть как эффективным, так и правильным, более разумно, чтобы оно не возвращало никакого значения вообще и требовало от клиентов использовать top() для проверки значения в верхней части стека.
pop
должен измениться, но они могут добавить новый методtoppop
который возвращает значение и который использует семантику перемещения, чтобы сделать это эффективно.