C++ template compilation error-рекурсивная зависимость типа или функции
Я написал класс шаблона, который дает ошибку компиляции
template<class T>
class Entity
{
string EntityName;
int EntitySize;
Entity<T*> pPrev;
Entity<T*> pNext;
public:
Entity<T>(const string & name, int size)
{
EntityName = name;
EntitySize = size;
}
//member functions
};
Я использую MSVC++ 2008, и ошибка:
неустранимая ошибка C1202: рекурсивный тип или контекст зависимости функции тоже комплекс
Я не написал никакой рекурсивной функции в своем классе. Тогда почему эта ошибка? Пожалуйста помочь.
5 ответов
хорошо. Я объясняю вам проблему, с которой вы столкнулись. Но прежде всего. Ты сказал:
Я написал класс шаблона, который предоставление ошибки компиляции
прежде всего, что касается C++,нет такой вещи, как "класс шаблона", есть только "шаблон класса"." способ чтения этой фразы - "шаблон для класса", в отличие от" шаблона функции", который является " шаблоном для функции." Снова: классы не определяют шаблоны, шаблоны определяют классы (и функции).* Цитата из здесь.
теперь вижу ошибку:
фатальная ошибка C1202: рекурсивный тип или контекст зависимости функции тоже комплекс
ошибка говорит все. .7.1
из стандарта очень хорошо объясняет причину вашей проблемы, давая вам даже пример, который очень близок к тому, что вы делаете. Так что мне даже не нужно писать одно мое слово. Вот .7.1
4 существует определенная реализация количество, указывающее ограничение на общая глубина рекурсии инстанцирования, которым может включать несколько шаблонов. результат бесконечного рекурсия в инстанцирования не определено. [ пример:
template < class T > class X { X<T >* p; // OK X<T*> a; //implicit generation of X<T> requires //the implicit instantiation of X<T*> which requires //the implicit instantiation of X<T**> which ... };
-конец примера ]
пожалуйста, читайте комментарий X<T*> a
, что в значительной степени и с тобой тоже. Таким образом, ваша проблема не из-за рекурсивной функции, а из-за рекурсивный экземпляр шаблона класса, вызывая из этих строк:
Entity<T*> pPrev;
Entity<T*> pNext;
надеюсь, это решит вашу проблему!
EDIT: но мне интересно, чего вы пытаетесь достичь с Entity<T*> pPrev
? Кажется, это опечатка, и вы, вероятно, хотели написать Entity<T>* pPrev
. То же самое с pNext
. Так ли это?
и Совет по улучшению дизайна : Вместо назначения используйте список инициализации членов. То есть, напишите свой конструктор следующим образом,
Entity<T>(const string & name, int size) : EntityName(name), EntitySize(size)
{
//all assignments moved to initialization list.
}
читать это : почему я должен предпочитать использовать список инициализации членов?
читать сообщение об ошибке более внимательно. "Слишком сложная" вещь не является рекурсивной функцией, это рекурсивная зависимость типа или функции. Тип Entity<T*>
зависит от типа Entity<T>
рекурсивно. Когда компилятор пытается сгенерировать код Entity<int>
, он должен будет выяснить Entity<int*>
(для реализации pPrev
и pNext
члены), что означает, что он должен будет выяснить Entity<int**>
, etc. - бесконечно. Это запрещено.
но это просто компилятор знает, что что-то не так. Он не знает, что не так, потому что не может думать о том, как программировать. (Если бы это было возможно, он просто написал бы вашу программу для вас.)
логическая ошибка в том, что Entity<T*>
означает "объект, который является сущностью с указателем типа шаблона на T". То, что вы действительно хотели, чтобы сделать связанный список, - это "указатель на объект, который является сущностью с типом шаблона T". Это пишется Entity<T>*
, С * вне угла скобки.
но это то, что вы пытаетесь создать свой собственный связанный список. не надо. Используйте стандартные контейнеры библиотеки. Если вы достаточно умны, чтобы использовать std::string
, вы должны быть достаточно умны, чтобы использовать контейнеры (std::vector
, std::list
, etc. - в смысле std::string
тоже контейнер, хотя и очень специального назначения) тоже.
ваше определение шаблона бесконечно рекурсивным. Вы определяете класс шаблона Entity<T>
, который содержит объекты типа Entity<T*>
в качестве членов. Объекты Entity<T*>
будет, согласно тому же определению, содержать объекты типа Entity<T**>
. Последний, в свою очередь, будет содержать объекты типа Entity<T***>
и так далее, бесконечно. Другими словами, ваше бесконечно рекурсивное определение шаблона не имеет смысла.
либо прекратить рекурсию, либо подумать о том, что вы действительно пытаетесь осуществлять. Я сильно подозреваю, что ваши определения членов должны были иметь тип Entity<T>*
, а не Entity<T*>
.
изменить
Entity<T*> pPrev; Entity<T*> pNext;
to
Entity<T> *pPrev; Entity<T> *pNext;
определение типа является рекурсивным...
вы написали рекурсивный тип. Сущность имеет другие члены сущности. Необходимо изменить члены сущности в указатель или ссылку.