Я пытаюсь создать класс двоичного дерева Tree
и класс двоичного дерева поиска BST
, который наследуется от Tree
, а также iterator
вложенных классов для каждого, где BST::iterator
наследуется от Tree::iterator
.
Теперь проблема в том, что некоторые функции деревьев должны возвращать iterator
своего собственного класса, например begin()
, end()
, search(T)
и т. Д. Это, похоже, не компилируется, потому что Tree::begin()
и BST::begin()
имеют "недопустимые ковариантные типы возврата".
После изучения указанной темы я понимаю , что заставляет компилятор жаловаться, но я не понимаю , почему это не разрешено. Кажется логичным, что в этом случае, например, Tree
должен возвращать объект типа Tree::iterator
, а BST
должен возвращать объект типа BST::iterator
.
Ниже приведен код, который должен проиллюстрировать, с чем я имею дело.
tree.h
template <class T>
class Tree {
protected:
class Node {
friend Tree;
T value;
Node* left;
Node* right;
};
Node* root;
public:
class iterator {
friend Tree;
Node* node;
public:
// operators and the like...
};
virtual iterator begin() const;
virtual iterator end() const;
virtual iterator search(const T& value) const;
};
BST.h
#include "Tree.h"
template <class T>
class BST : public Tree<T> {
protected:
class Node : public Tree<T>::Node {
friend BST;
};
using Tree<T>::root;
public:
class iterator : public Tree<T>::iterator {
friend BST;
};
using Tree<T>::begin;
using Tree<T>::end;
virtual iterator search(const T& value) const override;
};
Мне ясно, что в этом случае поиск пытается вернуть BST<T>::iterator
, и это недопустимо, потому что он переопределяет функцию, которая возвращает Tree<T>::iterator
, однако мне кажется логичным, что это должно быть разрешено, и я не уверен, как это должно быть сделано.
Кроме того, когда BST<T>
наследует begin()
и end()
, я предполагаю, что он наследует их так, что они возвращают Tree<T>::iterators
, хотя они действительно должны возвращать BST<T>::iterators
.
Что именно мне не хватает, и как этого добиться?