C++ template compilation error - recursive type or function dependency

后端 未结 5 773
醉话见心
醉话见心 2021-01-02 13:11

I wrote a template class which is giving compilation error

template
class Entity
{
    string EntityName;
    int  EntitySize;
    Entity

        
相关标签:
5条回答
  • 2021-01-02 13:24

    Change

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

    to

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

    Your type definition is recursive...

    0 讨论(0)
  • 2021-01-02 13:26

    Your template definition is infinitely recursive. You define template class Entity<T> that contains objects of type Entity<T*> as members. Objects Entity<T*> will, according to the same definition, contain objects of type Entity<T**>. The latter will in turn contain objects of type Entity<T***> and so on, as infinitum. In other words, your infinitely recursive template definition makes no sense.

    Either terminate the recursion or think about what it is you are really trying to implement. I strongly suspect that your member definitions were supposed to have type Entity<T>*, not Entity<T*>.

    0 讨论(0)
  • 2021-01-02 13:27

    Read the error message more closely. The "too complex" thing is not a recursive function, it's a recursive type or function dependency. The type Entity<T*> depends on the type Entity<T>, recursively. When the compiler tries to generate the code for Entity<int>, it will have to figure out Entity<int*> (in order to implement the pPrev and pNext members), which means it will have to figure out Entity<int**>, etc. - infinitely. That isn't allowed.

    But that's just how the compiler knows something is wrong. It doesn't know what is wrong, because it can't think about how to program. (If it could, it would just write your program for you.)

    The logical error is that Entity<T*> means "an object which is an Entity with template type pointer-to-T". What you really wanted, in order to make a linked list, is "a pointer to an object which is an Entity with template type T". That is spelled Entity<T>*, with the * outside the angle brackets.

    But the real problem is that you are trying to create your own linked list. Don't do that. Use the standard library containers. If you're smart enough to use std::string, you should be smart enough to use the containers (std::vector, std::list, etc. - in a sense, std::string is a container, too, albeit a very special-purpose one) too.

    0 讨论(0)
  • 2021-01-02 13:35

    Alright. I'm explaining you the problem you're facing. But first thing first. You said:

    I wrote a template class which is giving compilation error

    First of all, as far as C++ is concerned, there is no such thing as a "template class," there is only a "class template." The way to read that phrase is "a template for a class," as opposed to a "function template," which is "a template for a function." Again: classes do not define templates, templates define classes (and functions).* Quoted from here.

    Now, lets see the error:

    fatal error C1202: recursive type or function dependency context too complex

    The error says it all. $14.7.1 from the Standard explains the cause of your problem very well, giving you even an example which is very much close to what you're doing. So I don't even need to write a single word of my own. Here is $14.7.1

    4 There is an implementation-defined quantity that specifies the limit on the total depth of recursive instantiations, which could involve more than one template. The result of an infinite recursion in instantiation is undefined. [ Example:

    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 ]

    Please read the comment with X<T*> a, which is pretty much the case with you too. So your problem is not because of recursive function, it's rather because of recursive instantiation of class template, causing from these lines:

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

    Hope, it solves your problem!


    EDIT : But I'm wondering what are you trying to achieve with Entity<T*> pPrev? It seems its a typo, and you probably wanted to write Entity<T>* pPrev. Same with pNext. Is that so?

    And an advice to improve the design : Use Member Initialization list, instead of Assignment. That is, write your constructor the following way,

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

    Read this : Why should I prefer to use member initialization list?

    0 讨论(0)
  • 2021-01-02 13:36

    You have written a recursive type. Entity has other Entity members. You should change the Entity members into a pointer or reference.

    0 讨论(0)
提交回复
热议问题