0

I am trying to learn more about C++. This time with templated classes. I am trying to build a linked list class (Yes, I know about std::list) using templated data types. The problem that I am having deals with the forward declaration of the nested struct. What I am trying to do is have an encapsulating template class in which the underlying implementation is whatever, in this case a traditional linked list using struct. Here's some code:

/*

Linked List Class Library

Requires C++ 2011


*/


#include <stdlib.h>
#include "ctypesx.h"


#ifndef __CUSTOM_HEADER_FILE__LINKLIST_H__
#define __CUSTOM_HEADER_FILE__LINKLIST_H__



template <typename T> class linklist_c
  {
    private:
      typedef struct linklist_node_tag llnode_t;
      struct linklist_node_tag
        {
          llnode_t *next;
          llnode_t *prev;
          uint64 idx;
          uint32 key;
          void *data;
        };
      llnode_t *head;
      llnode_t *tail;
      llnode_t *curr;
      uint32 count;
      uint32 maxitem;
      uint64 nidx;
    public:
      // Constructors & Destructors

      linklist_c()
        {
          this->head = NULL;
          this->tail = NULL;
          this->curr = NULL;
          this->count = 0;
          this->maxitem = -1;
          this->nidx = 0;
        }

      linklist_c(uint32 maxitem)
        {
          this->head = NULL;
          this->tail = NULL;
          this->curr = NULL;
          this->count = 0;
          this->maxitem = maxitem;
          this->nidx = 0;
        }

      ~linklist_c()
        {
          llnode_t *xcurr;
          llnode_t *xnext;

          if (this->count > 0)
            {
              xcurr = this->head;
              while(xcurr != NULL)
                {
                  xnext = this->xcurr->next;
                  delete this->xcurr->data;
                  free(xcurr);
                  xcurr = xnext;
                }
              this->head = NULL;
              this->tail = NULL;
              this->curr = NULL;
              this->count = 0;
              this->nidx = 0;
            }
        }
  };


#endif

Now the issue that I have been having was reference to incomplete type in the destructor on the first two lines in the while loop. I have since added the this keyword and that seems to have solved the problem.

What I find puzzling is why?

This is the exact error as produced by clang++ (v2011 variant):

./linklist.h:71:18: error: member access into incomplete type 'llnode_t' (aka 'linklist_node_tag')
                  xnext = xcurr->next;
                               ^
./linklist.h:23:22: note: forward declaration of 'linklist_node_tag'
      typedef struct linklist_node_tag llnode_t;
                     ^
./linklist.h:72:17: error: member access into incomplete type 'llnode_t' (aka 'linklist_node_tag')
                  delete xcurr->data;

The variables xnext and xcurr are defined locally, so they should be on the stack, and they should be pointing directly to the struct. What am I missing?

I've done quite a bit of research on this without finding a clear answer.

Declaring a struct in a template class, undefined for member functions

Typedef inside template class doesn't work

Nested struct type in a template class

http://www.cplusplus.com/forum/beginner/94180/

Community
  • 1
  • 1
Daniel Rudy
  • 1,411
  • 12
  • 23
  • Why do you need the `llnode_t` type-alias? Why not simply name the structure `llnode_t` to begin with? In C++ the only difference between a `class` and a `struct` is the default visibility (`private` for classes, `public` for structures). – Some programmer dude Mar 15 '17 at 04:11
  • On a totally unrelated note, don't name anything using two leading underscores, those symbols are reserved for "the implementation" (compiler and standard library). I'm talking about your macro `__CUSTOM_HEADER_FILE__LINKLIST_H__`. See e.g. [this old question about it](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – Some programmer dude Mar 15 '17 at 04:15
  • By the way, the code you show do not match the error message. Please create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show the error messages from when you're building that. – Some programmer dude Mar 15 '17 at 04:40

0 Answers0