Bobby
Bobby

Reputation: 931

Referencing a struct declared in a template class

Alright, been at C++ for about 2 days now. Just done javascript before...

I'm making a template queue using a linked list. My compiler does not like it when I try to make a new Node struct from withink queue.cpp

//queue.h:
template <class Object>
class Queue
{
 public:
  Queue();                              // Default
  Queue(const Queue& original);         // Copy

  ~Queue();                             // Destructor

  const Queue& operator=(const Queue& rightHandSide);  //overloaded op

  bool isEmpty() const;

  bool enqueue(const Object& d);
  bool dequeue(Object& d);

 private:
  // Node definition
  struct Node
  {
    Object data;
    Node * next;
  };
  // Queue data members
  Node * front, * back;
};

So, in my copy contructor I need to make a new Node.

//queue.cpp
template <class Object>
Queue<Object>::Queue(const Queue& original)
{
  if (original.isEmpty()) {
    front = back = NULL;
  } else {
    front = back = new Queue::Node;                 //this is line 26
    front->data = original.front->data;
    Queue::Node * ptr = original.front->next;
    while (ptr != NULL) {
      back->next = new Queue<Object>::Node;
      back = back->next;
      back->data = ptr->data;
      ptr = ptr->next;
    }
  }
}

queue.cpp: In copy constructor âQueue<Object>::Queue(const Queue<Object>&)â:
queue.cpp:26: error: expected type-specifier
queue.cpp:26: error: expected `;'

Any help plz? Thanks in advance.

Upvotes: 2

Views: 1875

Answers (4)

user534498
user534498

Reputation: 3984

What's your compiler used? Your code shouldn't have any problem. Because when the name Queue is used inside the class, is equivalent to Queue<Object>.

It's in C++ standard,

Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used with or without a template-argument-list. When it is used without a template-argument-list, it is equivalent to the injected-class-name followed by the template-parameters of the class template enclosed in <>. When it is used with a template-argument-list, it refers to the specified class template specialization, which could be the current specialization or another specialization.

Upvotes: 1

iammilind
iammilind

Reputation: 69988

Once the copy constructor starts, <Object> will be implicitly added along with Queue whenever needed. For compatibility with all platforms you should declare like following:

front = back = new typename Queue::Node;  //this is line 26

Upvotes: 0

Potatoswatter
Potatoswatter

Reputation: 137810

Here's a slightly different suggestion:

// Node is defined within same "class { }", so it needs no "::" qualification
front = back = new Node;

In any case, your code as given compiles fine (http://ideone.com/UrLN0), so I wonder if there's something else outside what's here.

The identifier Queue with no template parameters refers to the current instantiation, inside the template itself.

Upvotes: 0

Anthony Williams
Anthony Williams

Reputation: 68581

Inside member functions of Queue, you can refer directly to Node.

front = back = new Node;                 //this is line 26

and

Node * ptr = original.front->next;

What you have inside the loop will also work, where you explicitly specify the template parameters. However, note that since Node is private, unless you make the template instantiations friends with each other, you must specify the template parameters for the current instantiation, so Queue<Object>::Node is fine, but Queue<int>::Node is not, apart from for Queue<int> itself.

Upvotes: 3

Related Questions