Ошибка: неполный тип, используемый в вложенном указателе имени
Существует 2 класса без шаблонов A
, B
, имеющих некоторые статические методы шаблонов.
Из класса A
вызывается статический метод в B
и из класса B
вызывается статический метод из A
. Исходный код только для иллюстрации (не настоящий код)...
хиджры
#include "B.h"
class A
{
public:
template <class T>
void f1 ()
{
T var1= ...;
T var2 = B::f4(T);
}
template <class T>
T f2()
{
return ...
}
};
#include "A.h"
class B
{
public:
template <class T>
void f3 ()
{
T var1= ...;
T var2 = A::f2(T); //Error
}
template <class T>
T f4()
{
return ...
}
};
У меня возникают проблемы с компилятором g++ в NetBeans. Во время компиляции возникает следующая ошибка: Ошибка: неполный тип A, используемый в вложенном спецификаторе имен, g++.
Я попытался добавить вперед декларации в оба класса, но ничего не получилось.
Существует более старая ошибка:
http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg01383.html
Ответы
Ответ 1
У вас есть круговая зависимость между вашими заголовочными файлами. Поскольку ваши классы настолько тесно переплетены, я бы предложил объединить их в один заголовочный файл, структурированный следующим образом:
class A
{
public:
template <class T>
void f1();
};
class B
{
...
};
template <class T>
void A::f1()
{
// Use full definition of class B
}
Если вы настаиваете на использовании отдельных файлов заголовков для A и B (что не будет иметь никакого значения, поскольку они в конечном итоге включают друг друга), вам нужно будет их перестроить, чтобы один из заголовков не включал другой, так что по крайней мере одна из зависимых функций шаблона должна быть определена в отдельном файле. Например:
// File "a_no_b.h"
class A
{
public:
template <typename T>
void f1();
};
// File "b_no_a.h"
class B
{
public:
template <typename T>
void f3();
};
// File "a.h"
#include "a_no_b.h"
#include "b_no_a.h"
template <typename T>
void A::f1()
{
// Use full definition of class B
}
// File "b.h"
#include "b_no_a.h"
#include "a_no_b.h"
template <typename T>
void B::f3()
{
// Use full definition of class A
}
Ответ 2
Поскольку существует циклическая зависимость, вам необходимо тщательно упорядочить объявления классов A
и B
, чтобы они были объявлены до определения функций-членов.
Вот A.h
:
#ifndef A_H
#define A_H 1
class A
{
public:
template <class T>
void f1 ();
template <class T>
T f2();
};
#include "B.h"
template <class T>
void A::f1()
{
T var1= ...;
T var2 = B::f4(T);
}
template <class T>
T A::f2()
{
return ...
}
#endif
Вот B.h
:
#ifndef B_H
#define B_H 1
class B
{
public:
template <class T>
void f3 ();
template <class T>
T f4();
};
#include "A.h"
template <class T>
void B::f3()
{
T var1= ...;
T var2 = A::f2(T);
}
template <class T>
T B::f4()
{
return ...
}
#endif
При таком подходе вы сможете сначала включить A.h
или B.h
и не иметь проблемы.
Ответ 3
Ваша проблема связана с циклическим заголовком.