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;
определение типа является рекурсивным...
вы написали рекурсивный тип. Сущность имеет другие члены сущности. Необходимо изменить члены сущности в указатель или ссылку.