Проблема в том, что B<T>::Node
нельзя использовать в этой строке, поскольку B<T>
еще не завершено.Без полного определения B
компилятор не может использовать вложенный тип.
Ошибка будет яснее, если вы используете:
template<typename T>
class B: public A<typename B<T>::Node> {
private:
struct Node{ int x=42;};
};
При этом g ++ дает более понятныйошибка со следующим кодом.
template<typename T>
class A {};
template<typename T>
class B: public A<typename B<T>::Node> {
private:
struct Node{ int x=42;};
};
int main()
{
B<int> b;
}
Ошибка компилятора:
socc.cc: In instantiation of ‘class B<int>’:
socc.cc:13:11: required from here
socc.cc:6:7: error: invalid use of incomplete type ‘class B<int>’
class B: public A<typename B<T>::Node> {
^
socc.cc:6:7: note: declaration of ‘class B<int>’
socc.cc: In function ‘int main()’:
socc.cc:13:11: warning: unused variable ‘b’ [-Wunused-variable]
B<int> b;
^
Вы прокомментировали
Более конкретно проблема заключается в том, что A
это дерево, а B
массив, похожий на массив, который сохраняет в памяти мои определенные Node
, используя структуру дерева.Поэтому контейнеру необходимо внутренне использовать дерево узлов.Я полагаю, что это более или менее распространенный дизайн для структур данных, так как обычно можно решить проблему?
Это требует агрегирования, а не наследования.
template<typename T>
class A { ... };
template <typename T>
class B {
private:
struct Node{ int x=42;};
A<Node> data;
};