unresolved external symbol in my Queue.cpp i'm trying to trace but can't find it?

I'm having trouble trying to figure out what the problem is because the file compiles.It's only when you try to execute that i get this error

" Linking...
Queue.obj : error LNK2001: unresolved external symbol "public: __thiscall Node<double>::Node<double>(void)" (??0?$Node@N@@QAE@XZ)
Debug/Queue.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

Queue.exe - 2 error(s), 0 warning(s)


any help would be much apprecciated. I'm still very new to c++
tyweed420Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Harisha M GEngineerCommented:
Hi tyweed420,
    Where is the code ?

Bye
---
Harish
tyweed420Author Commented:
sorry not sure what happened?

===========node.h
#include <iostream>
#include <string>
#include <fstream>
using namespace std;


template <class A_Type>
class Node
{
public:
      friend class Stack;
//friend class Queue;
Node(); //default constructor
//~Node(); //destructor
Node<A_Type> getName(Node*);
void setName(A_Type data, Node *node); //changes a name of given node
void addNodeStart(A_Type data);        //adds node to beginning of list
void addNodeEnd(A_Type data);          //adds node to end of list
void deleteNode(A_Type data);             //deletes specified node given the string
void Display();                       //displays entire list
int getSize();    
int sum();                    // returns size of list
Node* getLink(Node* n);
Node* getPrevious(Node* current);      //returns previous node of node you specify
Node* findNode(A_Type data);                 //finds a node given the string that node contains
//string deleteFirstNode() ;          
Node* getHead();
protected:
A_Type data;                           //name variable in node
int count;                             //count of nodes
Node *link,*head,*tail;                  
};

==============================


================node.cpp=====
//implementation of Node.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "Node.h"
using namespace std;


/*********
Constructor
********/
template <class A_Type>
Node<A_Type>::Node()
{
  head = NULL;
  tail=NULL;
  count=0;
 
}


template <class A_Type>
Node<A_Type>* Node<A_Type>::getLink(Node* n)
{
 return n->link;
}

/**********
Gets previous Node from current index
 ********/
template <class A_Type>
Node<A_Type>* Node<A_Type>::getPrevious(Node* index)
{
  if(index == head)
  {
    return head;
  }
  else
  {
    Node* iterator;
     iterator = head;
    while(iterator->link != index)
     {
     iterator = iterator->link;  
     }
     return iterator;
  }

}

/**********
Sets the name of given node in list
 ********/
template <class A_Type>
void Node<A_Type>::setName(A_Type data,Node *node)
{
  node->data=data;
}

/**********
Gets name of given node
 ********/
template <class A_Type>
Node<A_Type> Node<A_Type>::getName(Node *node)
{
   
     return node->data;
     
}

template <class A_Type>
int Node<A_Type>::getSize()
{
return count;
}

template <class A_Type>
Node<A_Type>* Node<A_Type>::getHead()
{return head;
}

/***********
Returns:Adds node to front of list
PreCondition: If list is null it will apply this node to head of list

************/
template <class A_Type>
void Node<A_Type>::addNodeStart(A_Type data)
{
     
   //check make sure list is not empty
     if(head == NULL)
     {
          head = new Node;
          tail = head; //<= not sure about this
      head->data=data;
       head->link=NULL;
     
      // head = tail;  //<= and not sure about this
     }
     else
     {
       
      Node *temp_ptr;
      temp_ptr = new Node;

      temp_ptr->data=data;

      temp_ptr->link = head;
      head = temp_ptr;
       
     }

    count++;

}

/**********
Adds new node to the end of list
 ********/
template <class A_Type>
void Node<A_Type>::addNodeEnd(A_Type data)
{
     
    //check make sure list is not empty
     if(head == NULL)
     {
     
       head = new Node;
       tail = head;
      head->data=data;
       head->link=NULL;
     
     }
     else
     {
       
      Node *temp_ptr;
      temp_ptr = new Node;
      temp_ptr->data=data;
       temp_ptr->link=NULL;

      tail->link=temp_ptr;
       tail= temp_ptr;
      //temp_ptr = getPrevious(tail);
     
       
     }

   count++;

}

/**********
Finds node in list given parameter string that node holds
 ********/
template <class A_Type>
Node<A_Type>* Node<A_Type>::findNode(A_Type data)
{
  Node* iterator;
  iterator= head;
  while(iterator->data != data)//<=== not sure if this will always test ok?
  {
       iterator = iterator->link;
  }
 
  return iterator;

}

/**********
Deletes front node in the list
 ********/
template <class A_Type>
void Node<A_Type>:: deleteNode(A_Type s)
{

  Node* temp_ptr;
  Node* n = findNode(s);  // finds the node we want to delete
  if(n == head )
  {
    temp_ptr = head;
    head = head->link;
  delete temp_ptr;
  }
  else if( n == tail)
  {
    temp_ptr = tail;
     tail = getPrevious(tail);
     tail->link = NULL;
     delete temp_ptr;
  }
count--;

}

/*
//This is inside Node.cpp
string &Node::deleteFirstNode()
{
     if(head == NULL) return string(""); //Check for empty linked list
     string &str = head->name; //Take copy of head vlaue
     temp = head;                    //Take copy of head for delete in future
     head = head->link;            //move to the next node
     delete temp;                     //Delete temporary
     return str;
}
*/

/**********
Display the entire list
 ********/
template <class A_Type>
void Node<A_Type>::Display()
{
  Node *iter;
cout << " the contents of the list: " << endl;
  for(iter = head; iter !=NULL; iter= iter->link)
  {
   
     cout << iter->data << " " ;
  }
  cout << endl;
  cout << "Size of linked list is: " << getSize() << endl;
}

template <class A_Type>
int Node<A_Type>::sum()
{

       Node *ptr;
       ptr = new Node;
      int sum=0;
       for(ptr = head ; ptr!=NULL;ptr=ptr->link)
       {sum+=ptr->data ;
       }
       return sum;
}
===========================

=================queue.h==================
//implementation of Queue.h
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

template <class t>
class Queue : public Node<t>
{
public:
      Queue();
//      ~Queue();
      void addItem(t data);
      void remove();
      bool isEmpty();
    void Display();
private:
      t data;
      Node<t> *front,*back;
};

========================================

========================queue.cpp
//implementation of Queue.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "Node.h"
#include "Queue.h"
using namespace std;


template <class t>
Queue<t>::Queue()
{
   front=NULL;
   back=NULL;
   
}

template <class t>
void Queue<t>::addItem(t data)
{
//      addNodeStart(data);

}


template <class t>
void Queue<t>::remove()
{
 //deleteNode(back);  
}

template <class t>
bool Queue<t>::isEmpty()
{
return (front == NULL);
}

template <class t>
void Queue<t>::Display()
{

      Node<t>::Display();
 
}


void main()
{
 Queue<double> q;
 //q.addItem(1);
 //q.addItem(2);
 //q.addItem(3);
 //q.Display();
 //q.remove()
}
=======================================
Harisha M GEngineerCommented:
tyweed420,
    You are having

Queue <double> q;

in queue.cpp
Double is not being supported. Change that to 'int' and it will run perfectly :)
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Harisha M GEngineerCommented:
jkr,
    Delete that one :)
Knut HunstadCommented:
You have to either:

A. Move all of Node.cpp into Node.h (let's you use any Node<ClassWhatever> in your code)
B. Leave Node.cpp where it is, but explicitly instantiate a double version by declaring:

template class Node<double>;

in Node.cpp. This restricts you to use only Node<double> in other files including Node.h. Which can be good or bad, depending on what you want...

As it is in your current code, Node.cpp doesn't instantiate (generate) any code for any Node<double> functions, since there is no call to any Node<double> in Node.cpp. Neither does queue.cpp, since it only knows the syntax of e.g. Node<double>::Node(), but not the code of this function.

Look up on "templates", "Instantiation" and "explicit instantiation" to find out more.
tyweed420Author Commented:
I don't understand? I thought the pupose of creating a template was so you could have a generic class that could take in,double,float,etc?  Why do i need to make a special class for double.

I'm missing something simple here in your respoonses.
Knut HunstadCommented:
Yes, that's the purpose. But the compiler can't guess all the classes you might want to use. Remember, Node<double> is one class, Node<int> another, even though both are created from the same template. Therefore it doesn't create a class from a template unless it is needed. Think of a macro:

#define YOUR_MACRO(x)  x=5

having this in your cpp-file doesn't really do anything. But when you call YOUR_MACRO(MyInt), then the code: MyInt=5 is inserted. Only with templates, when you have:

Queue<double> q;

the compiler realizes it needs the class Queue<double> as well as Node<double>. If you choose my suggestion A, you will get both the class Node<double> and Queue<double> in Queue.obj. If you follow suggestion B, the compiler generates a version of Node<double> in Node.obj (because of your explicit instantiation), which you presumably will link together with Queue.obj later. As your code is today, neither Queue.obj nor Node.obj will have any instantiation of Node<double>.

The most flexible and common way to handle templates, is suggestion A. If you don't know what to choose, choose A.
tyweed420Author Commented:
Ok so plan A is essentially getting rid of the Node.h and place everything in one file Node.cpp

also the reason why i thought it would work like a generic class was in Node.cpp i created a main and implemented
Node<string> p
Node<int> j
Node<iouble > k

and everything worked without having to do any additional instantiations. So, is the reason it is not working is because it's outside of the class?

Knut HunstadCommented:
Aha, so you didn't post all the code? Actually, if you had that main in Node.cpp, this would lead to:

Node<string>
Node<int>
Node<double>

beeing defined in Node.obj (Assuming the error with iouble was only in the transfer to this forum, not in your code?). The more elegant way to get Node<double> or other instantiations in Node.obj is like in suggestion B. Then you should be able to use Node<double> also in Queue.obj if you link with Node.obj somehow. But still you couldn't use e.g. Node<float> in Queue.obj without adding that class as well to Node.cpp. To achieve that (not having to change Node.h or Node.cpp when you want a new instantiation), you must follow suggestion A, which is to get rid of Node.cpp and place everything into Node.h, not the other way around!

Some more points, that hopefully clarify:

- With B (or your main in Node.cpp), Node<double> will be defined in Node.obj, since Node.cpp sees _both_ the template definition (not only the declaration) and at least one call to Node<double>. Queue.obj will not have Node<double> defined, but will hope to get it by linking, since it knows the syntax (through Node.h) and therefore can compile Queue.cpp without errors.
- With A, Queue.cpp has access to both the template definition and at least one call to Node<double> and therefore will include Node<double> in Queue.obj.

A good teacher could probably phrase this better :-)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.