Undefined reference to `LinkedList<int>::push_front(int) [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get “unresolved external symbol” errors when using templates?
LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>
template<class T> class LinkedList;
//------Node------
template<class T>
class Node {
private:
T data;
Node<T>* next;
public:
Node(){data = 0; next=0;}
Node(T data);
friend class LinkedList<T>;
};
//------Iterator------
template<class T>
class Iterator {
private:
Node<T> *current;
public:
friend class LinkedList<T>;
Iterator operator*();
};
//------LinkedList------
template<class T>
class LinkedList {
private:
Node<T> *head;
public:
LinkedList(){head=0;}
void push_front(T data);
void push_back(const T& data);
Iterator<T> begin();
Iterator<T> end();
};
#endif /* LINKEDLIST_H */
LinkedList.cpp
#include "LinkedList.h"
#include<iostream>
using namespace std;
//------Node------
template<class T>
Node<T>::Node(T data){
this.data = data;
}
//------LinkedList------
template<class T>
void LinkedList<T>::push_front(T data){
Node<T> *newNode = new Node<T>(data);
if(head==0){
head = newNode;
}
else{
newNode->next = head;
head = newNode;
}
}
template<class T>
void LinkedList<T>::push_back(const T& data){
Node<T> *newNode = new Node<T>(data);
if(head==0)
head = newNode;
else{
head->next = newNode;
}
}
//------Iterator------
template<class T>
Iterator<T> LinkedList<T>::begin(){
return head;
}
template<class T>
Iterator<T> Iterator<T>::operator*(){
}
main.cpp
#include "LinkedList.h"
using namespace std;
int main() {
LinkedList<int> list;
int input = 10;
list.push_front(input);
}
Hi, I am fairly new at c++ and I am trying to write my own LinkedList using templates.
I followed my book pretty closely and this is what I got. I am getting this error though.
/main.cpp:18: undefined reference to `LinkedList::push_front(int)'
I have no clue why, any ideas?

You are using templates in your Program. When you use templates, you have to write the code and the headers in the same file because the compiler needs to generate the code where it is used in the program.
You can do either this or include #inlcude "LinkedList.cpp" in main.cpp
This question might help you.
Why can templates only be implemented in the header file?

Related

Why does my compiler make me add the "this->" pointer to access parent variables from a child class [duplicate]

This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
Derived template-class access to base-class member-data
(3 answers)
Closed 3 years ago.
I'm coding a simple LinkedList class that is a child class to an abstract List class. After finishing the List class I started to code the LinkedList class, and I noticed that the compiler would not let me access the protected variables from the members of the List class directly, even though LinkedList is a child class of List. When I do not add the "this->" pointer before one of List's variables, I get an error that says the variable is not declared in the scope. I'm sure there is a simple explanation for this, but I can't figure out why the two protected variables in my List class and its members are not accessible from the members of the LinkedList class.
List:
template<typename T>
class List {
protected:
unsigned int numElements;
Node<T>* head;
public:
List();
~List();
virtual void append(T x) = 0;
virtual T remove() = 0;
virtual bool isEmpty();
};
template<typename T>
List<T>::List() {
numElements = 0;
head = NULL;
}
template<typename T>
List<T>::~List() {
while(NULL != head) {
Node<T>* newHead = head->getNext();
delete head;
head = newHead;
}
}
template<typename T>
bool List<T>::isEmpty() {
if (numElements)
return false;
return true;
}
LinkedList with one member example:
template<typename T>
class LinkedList: public List<T> {
public:
void append(T x);
T remove();
void append_tail(T x);
void insert(T x, int pos);
T remove_at(int pos);
void print();
int getNumElements();
};
template<typename T>
void LinkedList<T>::append(T x) {
// create a new node with its next as the head
Node<T>* appendNode = new Node<T>(x, this->head);
// set the head to this new node
this->head = appendNode;
this->numElements++;
}
Node class that is included (not very relevant)
#ifndef NODE_H
#define NODE_H
template<typename T>
class Node {
private:
T value;
Node * next;
public:
Node(T v, Node * n);
T getValue() const;
Node * getNext() const;
void setNext(Node * p);
};
template<typename T>
Node<T>::Node(T v, Node * n) {
value = v;
next = n;
}
template<typename T>
T Node<T>::getValue() const {
return value;
}
template<typename T>
Node<T>* Node<T>::getNext() const {
return next;
}
template<typename T>
void Node<T>::setNext(Node * n) {
this->next = n;
}
#endif

Friend class declaration error [duplicate]

This question already has answers here:
Understanding templates in c++
(2 answers)
Closed 7 years ago.
I'm implementing a singly linked list. Here's the node class
template <typename T> class node{
friend class slist<T>;
public:
explicit node():data(0), next(NULL){}
private:
T data;
node<T> *next;
};
And here's the list class.
template<typename T> class slist{
public:
slist():head(NULL){}
bool empty(){
return head == NULL;
}
void add_front(const T& data){
if(head == NULL){
node<T>* n = new node<T>();
n->data = data;
n->next = NULL;
head = n;
return;
}
node<T>* n = new node<T>();
n->data = data;
n->next = head;
head = n;
}
void remove_front(){
if(head == NULL) return;
node<T>* old = head;
head = old->next;
delete old;
}
void print_list(){
if(head == NULL) return;
while(!empty()){
std::cout<<head->data<<std::endl;
head = head->next;
}
}
~slist(){
while(!empty()) remove_front();
}
private:
node<T>* head;
};
The implementation works perfectly fine if I declare the members in the node as public. However the moment I declare them private and make the slist a friend class, I get the following error.
In file included from src.cpp:3:
./slist.hpp:5:28: error: redefinition of 'slist' as different kind of symbol
template<typename T> class slist{
^
./node.hpp:4:15: note: previous definition is here
friend class slist;
I can obviously find other implementation of single linked list, but I'm trying to understand what's going wrong here. So please refrain from unsolicited advice as "google it". Thanks.
You need to forward declare the List class as a template class:
#include <iostream>
template<typename T> class List; //<< fwd decl
template<typename T> class Node {
int i;
public:
friend class List<T>; //<< usage same as you have now
Node() : i(123) {}
int value() { return i; }
};
template<typename T> class List { //<< definition
public:
List(Node<T>* node) { node->i++; }
};
int main() {
Node<int> node{};
List<int> list{&node};
std::cout << node.value() << "\n";
}
http://ideone.com/2RUWgj
The friend class declaration needs it's own template parameter declaration without shadowing the enclosing classes template parameters:
template<typename U> class slist; // Forward declare slist
template <typename T>
class node{
template<typename U> // <<<<<
friend class slist<U>;
// ^ <<<<<
// ...
};

My program not discovery the functions in struct

My program not discovery the functions returnTest or others new function that are create in struct Node. The g++ compiler return this error:
linkedList.cpp: In instantiation of 'void LinkedList<T>::insert(T) [with T = int]':
linkedList.cpp:37:22: required from here
linkedList.cpp:31:13: error: 'struct LinkedList<int>::Node' has no member named
'returnTest' std::cout << auxHead->returnTest();
My files are:
Main.cpp
#include "linkedList.hpp"
#include <iostream>
#include <cstdlib>
template<class T> LinkedList<T>::LinkedList()
{
node = NULL;
}
template<class T> LinkedList<T>::~LinkedList()
{
}
template<class T> bool LinkedList<T>::isEmpty(){
}
template<class T> int LinkedList<T>::size(){
if (node == NULL)
return 0;
}
template<class T> void LinkedList<T>::insert(T element){
Node *auxHead = node;
if (auxHead == NULL){
Node* newNode = new Node();
newNode->data = element;
node = newNode;
}else{
std::cout << auxHead->returnTest();
}
}
int main(){
LinkedList<int> *newLinked = new LinkedList<int>();
newLinked->insert(55);
newLinked->insert(55);
return 0;
}
LinkedList.hpp
#ifndef __LINKEDLIST_H_
#define __LINKEDLIST_H_
#include <stdio.h>
template <class T> class LinkedList {
private:
struct Node {
T data = NULL;
Node *next;
T getData(){
return data;
}
Node getNext(){
return next;
}
int returnTest(){
return -1;
}
T isNIL(){
return (data == NULL);
}
};
Node *node = NULL;
public:
LinkedList();
~LinkedList();
bool isEmpty();
int size();
void insert (T&);
};
#endif
My g++ version is 4.8.1. Please ignore the method size()
You cannot put to implementation of template class/function. just put the implementation (which is in .cpp) into header file.

C++ Linked Lists with Multi-Files

I am a bit new to using multi-files. I have this very simple code for a linked list, but when I debug, it "stops working".
This problem has occured with me several times before. I want to know is there something wrong with my "linked list" code? Or is something wrong with the multi-files organization?
Any help would be highly appreciated.
======================================
//linkedListMAIN.cpp
#include "linkedlist.cpp"
void main()
{
linkList<int> l;
l.append(5);
l.traverse();
}
======================================
//linkedList.h
#include<iostream>
using namespace std;
template <class T>
class linkList
{
private:
struct node
{
T data;
node *next;
};
node *head;
node *tail;
int noOfEl;
public:
linkList()
{
noOfEl = 0;
head=tail=NULL;
}
void traverse();
int length();
void insertAt(T, int);
T delAt(int);
void append(T);
void clear();
};
======================================
//linkedList.cpp
#include "linkedlist.h"
template <class T>
void linkList<T>:: traverse()
{
node<T> *current=head;
if(head == NULL)
{
cout<<"List empty."<<endl;
}
while(current != NULL)
{
cout<<current->data;
current = current->next;
}
}
template <class T>
void linkList<T>::append(T data)
{
node< *newNode= new node;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
noOfEl++;
}
You should not include the .cpp in inkedListMAIN.cpp but the header (.h). Also unless you are using c++11 you will have to put the class definition of templated classes in the header.

Difficulty with template class

Okay, guys i have been trying to define a Stack , each node also being of template type but i get dozen different types of errors when the prog tries to compile. i will paste the program which uses a char-type stack and tries to pop letter 'e'
#ifndef STACK_LIST_H
#define STACK_LIST_H
#include "List.h"
using namespace std;
template <class T>
class Stack {
public:
T pop();
void push(T x);
T isEmpty();
T top();
private:
int size;
Node<T> * headNode;
Node<T> * currentNode;
};
#endif
Now the function definitions:
#include <iostream>
#include "Stack_list.h"
using namespace std;
template <class T>
T Stack<T>::pop(){
T x = headNode->get();
Node<T>* p = new Node<T>::Node();
p = headNode;
headNode = headNode->getNext();
delete p;
return x; }
template <class T>
void Stack<T>::push(T x){
Node<T>* newNode = new Node<T>::Node();
newNode->setNext(headNode);
newNode->set(x);
headNode=newNode;
}
template <class T>
int Stack<T>::isEmpty(){
return (headNode ==NULL);}
template <class T>
T Stack<T>::top(){
return headNode->get();
}
now the template class node:
#ifndef LIST_H
#define LIST_H
using namespace std;
/* The Node class */
template <class T>
class Node
{
public:
Node(T here){object=here;};
T get() { return object; };
void set(T object) { this->object = object; };
Node<T>* getNext() { return nextNode; };
void setNext(Node<T>* nextNode) { this->nextNode = nextNode; };
Node<T>* getPrev(){ return prevNode;};
void setPrev(Node<T>* prevNode){this->prevNode=prevNode;};
private:
T object;
Node<T>* nextNode;
Node<T>* prevNode;
};
#endif
and finally the program that evokes the classes:
#include <iostream>
#include "Stack_list.cpp"
using namespace std;
int main(){
Stack <char>s;
s.push("e");
cout<<s.pop();
}
As you can see, this is my first try at template classes. In definitions of Stack::pop() and push(T) it says, "expected type-specifier before ‘Node’"
Node<T>* newNode = new Node() is inconsistent. Is Node a class or a class template? The first time that you mention it, you treat it as a template and instantiate it with T, but the second time you treat it as a class. It can't be both.
Your method definition signatures are:
T Stack<T>::pop()
but they should be
template<typename T>
T Stack<T>::pop()
Also, since Stack uses Node, you have to include Node.h in Stack.h.
Furthermore - in Stack you declared T isEmpty(); but implemented it as int Stack<T>::isEmpty(). Stick to one return type (probably bool is more appropriate here, but int is also OK).
Lastly:
Stack <char>s;
s.push("e");
The template specialization is char, but "e" is a const char*. The correct way would be:
Stack <char>s;
s.push('e'); // <- note the single quotes