C ++模板编译错误 - 递归类型或函数依赖

时间:2010-12-05 07:39:15

标签: c++ templates

我写了一个给出编译错误的模板类

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 个答案:

答案 0 :(得分:11)

好的。我正在向你解释你所面临的问题。但首先要做的事情。你说:

  

我写了一个模板类   给出编译错误

首先,就C ++而言,没有“模板类”这样的东西,只有“类模板”。读取该短语的方式是“类的模板,“与”函数模板相对,“是”函数的模板“。同样:类不定义模板,模板定义类(和函数)。*引自here

现在,让我们看一下错误:

  

致命错误C1202:递归类型或   函数依赖上下文也是   复杂的

错误说明了一切。标准$14.7.1非常好地解释了你的问题的原因,给你一个与你正在做的非常接近的例子。所以我甚至不需要写一个我自己的单词。这是$14.7.1

  

4 有一个实现定义   指定限制的数量   递归的总深度   实例化,其中       可能涉及多个模板。 无限的结果   实例化中的递归是   undefined。 [例如:

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 ...
};
     

-end example]

请阅读X<T*> a的评论,这也是你的情况。所以你的问题不是因为递归函数,而是因为类模板的递归实例化,导致这些行:

  Entity<T*> pPrev;
  Entity<T*> pNext;

希望,它解决了你的问题!


编辑:但我想知道你想用Entity<T*> pPrev做些什么?这似乎是一个错字,你可能想写Entity<T>* pPrev。与pNext相同。是这样吗?

改进设计的建议:使用“成员初始化”列表,而不是“分配”。也就是说,按以下方式编写构造函数,

    Entity<T>(const string & name, int size) : EntityName(name), EntitySize(size)
    {
       //all assignments moved to initialization list.
    }

阅读本文:Why should I prefer to use member initialization list?

答案 1 :(得分:7)

更密切地阅读错误消息。 “太复杂”的东西不是递归函数,它是递归的类型或函数依赖。类型Entity<T*>递归地取决于类型Entity<T>。当编译器尝试生成Entity<int>的代码时,它必须找出Entity<int*>(为了实现pPrevpNext成员),这意味着它将必须无限地找出Entity<int**>等。这是不允许的。

但这就是编译器知道错误的原因。它不知道出了什么问题,因为它无法思考如何编程。 (如果可以的话,它只会为你编写程序。)

逻辑错误是Entity<T*>表示“一个对象,它是一个具有模板类型指针到T的实体”。为了制作链表,你真正想要的是“指向对象的指针,该对象是具有模板类型T的实体”。拼写为Entity<T>*,尖括号外有*。

但真正的问题是您尝试创建自己的链接列表。 不要那样做。使用标准库容器。如果你足够聪明,可以使用std::string,那么你应该足够聪明地使用容器(std::vectorstd::list等 - 从某种意义上说,std::string是一个容器,也是一个非常特殊的容器。

答案 2 :(得分:3)

您的模板定义是无限递归的。您将包含类型为Entity<T>的对象的模板类Entity<T*>定义为成员。根据相同的定义,对象Entity<T*>将包含Entity<T**>类型的对象。后者将依次包含类型为Entity<T***>的对象,依此类推,无穷无尽。换句话说,您的无限递归模板定义毫无意义。

终止递归或考虑你真正想要实现的内容。我强烈怀疑您的成员定义应该是Entity<T>*类型,而不是Entity<T*>

答案 3 :(得分:2)

更改

    Entity<T*> pPrev;
    Entity<T*> pNext;

    Entity<T> *pPrev;
    Entity<T> *pNext;

您的类型定义是递归的......

答案 4 :(得分:-1)

你写了一个递归类型。实体有其他实体成员。您应该将实体成员更改为指针或引用。