-1

Why do templates let you get around incomplete types? I was following an example in a textbook on Nodes, Linked lists and Iterators. I noticed he used a pointer to instances of Lists and Nodes in the Iterator class, but then he also created a method in the List class to return an Iterator for that class. When I tried to implement it myself to save time I didn't template it and chose int data instead, however I would get an error of incomplete type for my Iterator-typed method. When I followed the template notation it worked fine.

template<class Datatype> class Object;    
template<class Datatype> class List;
template<class Datatype> class Helper;

template <class Datatype>
class Object {
public:
    Object() : m_data(), next(0) {}
    Datatype m_data;
    Object<Datatype>* next;
};

template <class Datatype>
class List{
public:
    List() : m_head(0), m_tail(0) {}
    Object<Datatype>* m_head;
    Object<Datatype>* m_tail;
    int m_count;
    Helper<Datatype> getHelper()
    {
        return Helper<Datatype>( m_head, this);
    }
};
template <class Datatype>
class Helper {
public:
    Helper( Object<Datatype>* p_node, List<Datatype>* p_list);
    Object<Datatype>* m_node;
    List<Datatype>* m_list;

};

edit: There may have been some confusion to what my question was referring to. It was referring to the class-typed method

Helper<Datatype> getHelper()

When hard-typed it results in an error of incomplete type. I was wondering how templates got around this? I have some idea that its because a template allows types of different memory sizes then it doesn't handle that methods memory return size until compile-time. I'm quite curious as to how this works, if anyone has an answer I'd appreciate it.

Congomon
  • 13
  • 3
  • I'm new here, took me a little while to figure out how to do that. This was just a basic functionality test @LuchianGrigore – Congomon Feb 06 '15 at 10:37
  • Is it just MSVC that lets you get away with it, or GCC and Clang too? They have different instantiation mechanisms, and MSVC often lets you do things that are not technically allowed. – Sebastian Redl Feb 07 '15 at 09:55
  • I was just using Xcode for my test, the real example comes from Data Structures for Game Programmers by Ron Penton, so I'm assuming you can get away with it in most instances. @SebastianRedl – Congomon Feb 07 '15 at 11:12

1 Answers1

0

Lines 1-3 in the code that you've posted forward-declare all your classes, so pointers to instances of these can now be resolved by the compiler, before it has seen the full definition.

The same technique works in the non-template case.

Edit after updated OP: In non-template classes, to use an actual object (as opposed to just a pointer) you need to have the full class definition available. So the forward declarations are not enough and it will give you an error when you try to return an instance of Helper.

Templates are not instantiated until you use them, which in your case is after you have provided a full definition of Helper, so the compiler has no problem finding it.

Lubo Antonov
  • 2,301
  • 14
  • 18
  • I understand the forward declarations allow the pointers to instances but my question referred to the actual instance method: Helper getHelper() that is used in the List class, when non templated it gives an error of incomplete type – Congomon Feb 06 '15 at 20:49
  • Think of the template as a sophisticated macro (it's actually very wrong, but a good analogy for this purpose). You write a macro at one point, and you use it (instantiate the template) at another point. The actual compilation happens when you use the macro. It does not matter what is known or not when you define the macro. The checks happen when you use it, and by then the compiler has enough information to pass the checks. –  Feb 12 '15 at 14:53