linker problems
Oct 25, 2009 at 8:10pm UTC
hey,im having linker error issues with this program im writing
example:
[Linker error] undefined reference to `llist<int>::llist()'
header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#ifndef LList_h_
#define LList_h_
#include <iostream>
template <class itemtype>
class llist
{
template <itemtype>
friend std::ostream& operator <<(std::ostream & , llist<itemtype> &);
private :
struct nodetype
{
itemtype item;
nodetype *next;
};
nodetype *first, *last;
public :
llist();
void firstinsert(itemtype);
void frontinsert(itemtype);
void endinsert(itemtype);
void inorderinsert(itemtype);
bool search(itemtype);
bool remove (itemtype);
bool listempty();
itemtype firstitem();
itemtype lastitem();
~llist();
};
#endif
implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
#include "LList.h"
#include<iostream>
template <class itemtype>
llist<itemtype>::llist()
{
first=last=0;
}
template <class itemtype>
void llist<itemtype>::firstinsert(itemtype x)
{
first= new nodetype;
last= first;
first->item =x;
first->next = 0;
}
template <class itemtype>
void llist<itemtype>::frontinsert(itemtype x)
{
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=first;
first=newnode;
}
template <class itemtype>
void llist<itemtype>::endinsert(itemtype x)
{
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=0;
last->next=newnode;
last=newnode;
}
template <class itemtype>
void llist<itemtype>::inorderinsert(itemtype x)
{
nodetype *cur;
nodetype *prev;
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=0;
if (x<=first->item)
{
newnode->next=first;
first=newnode;
}
else if (x>=last->item)
{
last->next=newnode;
last=newnode;
}
else
{
prev=first;
cur=first->next;
while (x>cur->item)
{
prev=cur;
cur=cur->next;
}
}
}
template <class itemtype>
bool llist<itemtype>::listempty()
{
return (first==0);
}
template <class itemtype>
itemtype llist<itemtype>::firstitem()
{
return first->item;
}
template <class itemtype>
itemtype llist<itemtype>::lastitem()
{
return last->item;
}
template <class itemtype>
bool llist<itemtype>::search(itemtype x)
{
nodetype *cur;
cur=first;
while ((cur!=0)&&(x!=cur->item))
{
cur=cur->next;
}
return (cur!=0);
}
template <class itemtype>
llist<itemtype>::~llist()
{
nodetype *delnode;
while (first!=0)
{
delnode=first;
first=first->next;
delete delnode;
}
}
template <class itemtype>
bool llist<itemtype>::remove (itemtype x)
{
nodetype *cur, *prev;
nodetype *delnode;
prev=0;
cur=first;
while ((cur!=0)&&(x!=cur->item))
{
prev=cur;
cur=cur->next;
if (cur==0)
return 0;
else
delnode=cur;
if (prev==0)
{
first=first->next;
}
else
{
prev->next=cur->next;
if (cur==last)
last=prev;
}
delete delnode;
return 1;
}
}
template <class itemtype>
std::ostream& operator <<(std::ostream &output,llist<itemtype> &l)
{
typename llist<itemtype>::nodetype *cur;
cur=l.first;
while (cur!=0)
{
output<<cur->item<<"|" ;
cur=cur->next;
}
return output;
}
main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include "LList.h"
#include<iostream>
int main()
{
llist<int > i;
llist<char > c;
i.firstinsert(1);
i.frontinsert(2);
i.endinsert(4);
i.inorderinsert(3);
c.firstinsert('c' );
c.frontinsert('a' );
c.endinsert('r' );
c.inorderinsert('t' );
std::cout<<c<<std::endl;
std::cout<<i<<std::endl;
system("pause" );
return 0;
}
any help is appreciated
Oct 25, 2009 at 9:01pm UTC
Move all your implementation stuff from LList.cpp and put it into LList.h
It is the easiest way (but not the only way) to do template stuff
Last edited on Oct 25, 2009 at 9:03pm UTC
Oct 26, 2009 at 4:26am UTC
unfortunately i need to have two different files.Any other way i can do it?
Oct 26, 2009 at 4:33am UTC
If your compiler doesn't support the export keyword, no. There is no other way.
Oct 26, 2009 at 4:38am UTC
Why do you need separate H and CPP files?
One alternative is:
As you need a
llist<int> and a
llist<char>
Add the following explicit instantiation commands at the end of the llist.cpp file:
1 2
template class llist<int >;
template class llist<char >;
you obviously will have to make sure the cpp file gets compiled as well.
Oct 27, 2009 at 1:36pm UTC
ok,that worked but now i get [Linker error] undefined reference to `operator<<(std::ostream&, llist<char>&)'
for this function:
1 2 3 4 5 6 7 8 9 10 11 12
template <class itemtype>
std::ostream& operator <<(std::ostream &output,llist<itemtype> &l)
{
typename llist<itemtype>::nodetype *cur;
cur=l.first;
while (cur!=0)
{
output<<cur->item<<"|" ;
cur=cur->next;
}
return output;
}
any help is appreciated
Oct 27, 2009 at 7:00pm UTC
updated code:
header:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#ifndef LList_h_
#define LList_h_
#include <iostream>
using namespace std;
template <class itemtype>
class llist
{
template <itemtype>
friend ostream& operator <<(ostream & , const llist&);
private :
struct nodetype
{
itemtype item;
nodetype *next;
};
nodetype *first, *last;
public :
llist();
void firstinsert(itemtype);
void frontinsert(itemtype);
void endinsert(itemtype);
void inorderinsert(itemtype);
bool search(itemtype);
bool Delete (itemtype);
bool listempty();
itemtype firstitem();
itemtype lastitem();
~llist();
};
#endif
implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
#include "LList.h"
#include<iostream>
template <class itemtype>
llist<itemtype>::llist()
{
first=last=0;
}
template <class itemtype>
void llist<itemtype>::firstinsert(itemtype x)
{
first= new nodetype;
last= first;
first->item =x;
first->next = 0;
}
template <class itemtype>
void llist<itemtype>::frontinsert(itemtype x)
{
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=first;
first=newnode;
}
template <class itemtype>
void llist<itemtype>::endinsert(itemtype x)
{
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=0;
last->next=newnode;
last=newnode;
}
template <class itemtype>
void llist<itemtype>::inorderinsert(itemtype x)
{
nodetype *cur;
nodetype *prev;
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=0;
if (x<=first->item)
{
newnode->next=first;
first=newnode;
}
else if (x>=last->item)
{
last->next=newnode;
last=newnode;
}
else
{
prev=first;
cur=first->next;
while (x>cur->item)
{
prev=cur;
cur=cur->next;
}
}
}
template <class itemtype>
bool llist<itemtype>::listempty()
{
return (first==0);
}
template <class itemtype>
itemtype llist<itemtype>::firstitem()
{
return first->item;
}
template <class itemtype>
itemtype llist<itemtype>::lastitem()
{
return last->item;
}
template <class itemtype>
bool llist<itemtype>::search(itemtype x)
{
nodetype *cur;
cur=first;
while ((cur!=0)&&(x!=cur->item))
{
cur=cur->next;
}
return (cur!=0);
}
template <class itemtype>
llist<itemtype>::~llist()
{
nodetype *delnode;
while (first!=0)
{
delnode=first;
first=first->next;
delete delnode;
}
}
template <class itemtype>
bool llist<itemtype>::Delete (itemtype x)
{
nodetype *cur, *prev;
nodetype *delnode;
prev=0;
cur=first;
while ((cur!=0)&&(x!=cur->item))
{
prev=cur;
cur=cur->next;
if (cur==0)
return 0;
else
delnode=cur;
if (prev==0)
{
first=first->next;
}
else
{
prev->next=cur->next;
if (cur==last)
last=prev;
}
delete delnode;
return 1;
}
}
template <class itemtype>
ostream& operator <<(ostream &output,llist<itemtype> const &l)
{
typename llist<itemtype>::nodetype *cur;
cur=l.first;
while (cur!=0)
{
output<<cur->item<<"|" ;
cur=cur->next;
}
return output;
}
template class llist<int >;
template class llist<char >;
main:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include "LList.h"
#include<iostream>
using namespace std;
int main()
{
llist<int > i;
llist<char > c;
i.firstinsert(1);
i.frontinsert(2);
i.endinsert(4);
i.inorderinsert(3);
c.firstinsert('c' );
c.frontinsert('a' );
c.endinsert('r' );
c.inorderinsert('t' );
cout<<c<<endl;
cout<<i<<endl;
system("pause" );
return 0;
}
help is still appreciated
Last edited on Oct 27, 2009 at 7:01pm UTC
Oct 27, 2009 at 10:46pm UTC
You explicitly instantiate the operator << function the same way as you did before.
(Note: I tend to use
template <typename X>
rather than
template <class X>
)
The header file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#ifndef LList_h_
#define LList_h_
#include <iostream>
//using namespace std;
template <class itemtype>
class llist
{
// NOTE: GG has changed the way this friend function has been declared
template <typename T>
friend std::ostream& operator <<(std::ostream & , const llist<T>&);
private :
struct nodetype
{
itemtype item;
nodetype *next;
};
nodetype *first, *last;
public :
llist();
void firstinsert(itemtype);
void frontinsert(itemtype);
void endinsert(itemtype);
void inorderinsert(itemtype);
bool search(itemtype);
bool Delete (itemtype);
bool listempty();
itemtype firstitem();
itemtype lastitem();
~llist();
};
#endif
The implementation file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#include "LList.h"
#include<iostream>
using namespace std;
template <class itemtype>
llist<itemtype>::llist()
{
first = last = 0;
}
template <class itemtype>
void llist<itemtype>::firstinsert(itemtype x)
{
first = new nodetype;
last = first;
first->item = x;
first->next = 0;
}
template <class itemtype>
void llist<itemtype>::frontinsert(itemtype x)
{
nodetype *newnode;
newnode = new nodetype;
newnode->item = x;
newnode->next = first;
first = newnode;
}
template <class itemtype>
void llist<itemtype>::endinsert(itemtype x)
{
nodetype *newnode;
newnode = new nodetype;
newnode->item = x;
newnode->next = 0;
last->next = newnode;
last = newnode;
}
template <class itemtype>
void llist<itemtype>::inorderinsert(itemtype x)
{
nodetype *cur;
nodetype *prev;
nodetype *newnode;
newnode = new nodetype;
newnode->item = x;
newnode->next = 0;
if (x <= first->item)
{
newnode->next = first;
first = newnode;
}
else if (x >= last->item)
{
last->next = newnode;
last = newnode;
}
else
{
prev = first;
cur = first->next;
while (x > cur->item)
{
prev = cur;
cur = cur->next;
}
}
}
template <class itemtype>
bool llist<itemtype>::listempty()
{
return (first == 0);
}
template <class itemtype>
itemtype llist<itemtype>::firstitem()
{
return first->item;
}
template <class itemtype>
itemtype llist<itemtype>::lastitem()
{
return last->item;
}
template <class itemtype>
bool llist<itemtype>::search(itemtype x)
{
nodetype *cur;
cur = first;
while ((cur != 0) && (x != cur->item))
{
cur = cur->next;
}
return (cur != 0);
}
template <class itemtype>
llist<itemtype>::~llist()
{
nodetype *delnode;
while (first != 0)
{
delnode = first;
first = first->next;
delete delnode;
}
}
template <class itemtype>
bool llist<itemtype>::Delete (itemtype x)
{
nodetype *cur, *prev;
nodetype *delnode;
prev = 0;
cur = first;
while ((cur != 0) && (x != cur->item))
{
prev = cur;
cur = cur->next;
if (cur == 0)
return 0;
else
delnode = cur;
if (prev == 0)
{
first = first->next;
}
else
{
prev->next = cur->next;
if (cur == last)
last = prev;
}
delete delnode;
return 1;
}
return false ; //NOTE: This function should return a value - this line added by GG
}
template <class T>
ostream& operator <<(std::ostream &output, llist<T> const &l)
{
typename llist<T>::nodetype *cur;
cur = l.first;
while (cur != 0)
{
output << cur->item << "|" ;
cur = cur->next;
}
return output;
}
/************************************************/
template class llist<int >;
template class llist<char >;
template ostream& operator << (ostream &output, llist<int > const &l); //<= See here
template ostream& operator << (ostream &output, llist<char > const &l);//<= See here
Last edited on Oct 27, 2009 at 11:14pm UTC
Oct 28, 2009 at 1:54am UTC
im not using GG,im using Dev. Anyway i can do it with that? Because i tried this and im still getting more errors than needed.
Oct 28, 2009 at 6:23am UTC
GG = G uestG ulkan
Oct 28, 2009 at 6:41am UTC
works for me (using Dev c++)
Not tried using MSVC
Oct 28, 2009 at 1:45pm UTC
Ah,sorry dude. i typed in what you did. Im still getting the same errors
specifically:
[Linker error] undefined reference to `operator<<(std::ostream&, llist<char> const&)'
[Linker error] undefined reference to `operator<<(std::ostream&, llist<int> const&)'
header
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#ifndef LList_h_
#define LList_h_
#include <iostream>
template <class itemtype>
class llist
{
template <typename t>
friend std::ostream& operator <<(std::ostream & , const llist<t>&);
private :
struct nodetype
{
itemtype item;
nodetype *next;
};
nodetype *first, *last;
public :
llist();
void firstinsert(itemtype);
void frontinsert(itemtype);
void endinsert(itemtype);
void inorderinsert(itemtype);
bool search(itemtype);
bool Delete (itemtype);
bool listempty();
itemtype firstitem();
itemtype lastitem();
~llist();
};
#endif
implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
#include "LList.h"
#include<iostream>
template <class itemtype>
llist<itemtype>::llist()
{
first=last=0;
}
template <class itemtype>
void llist<itemtype>::firstinsert(itemtype x)
{
first= new nodetype;
last= first;
first->item =x;
first->next = 0;
}
template <class itemtype>
void llist<itemtype>::frontinsert(itemtype x)
{
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=first;
first=newnode;
}
template <class itemtype>
void llist<itemtype>::endinsert(itemtype x)
{
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=0;
last->next=newnode;
last=newnode;
}
template <class itemtype>
void llist<itemtype>::inorderinsert(itemtype x)
{
nodetype *cur;
nodetype *prev;
nodetype *newnode;
newnode= new nodetype;
newnode->item =x;
newnode->next=0;
if (x<=first->item)
{
newnode->next=first;
first=newnode;
}
else if (x>=last->item)
{
last->next=newnode;
last=newnode;
}
else
{
prev=first;
cur=first->next;
while (x>cur->item)
{
prev=cur;
cur=cur->next;
}
}
}
template <class itemtype>
bool llist<itemtype>::listempty()
{
return (first==0);
}
template <class itemtype>
itemtype llist<itemtype>::firstitem()
{
return first->item;
}
template <class itemtype>
itemtype llist<itemtype>::lastitem()
{
return last->item;
}
template <class itemtype>
bool llist<itemtype>::search(itemtype x)
{
nodetype *cur;
cur=first;
while ((cur!=0)&&(x!=cur->item))
{
cur=cur->next;
}
return (cur!=0);
}
template <class itemtype>
llist<itemtype>::~llist()
{
nodetype *delnode;
while (first!=0)
{
delnode=first;
first=first->next;
delete delnode;
}
}
template <class itemtype>
bool llist<itemtype>::Delete (itemtype x)
{
nodetype *cur, *prev;
nodetype *delnode;
prev=0;
cur=first;
while ((cur!=0)&&(x!=cur->item))
{
prev=cur;
cur=cur->next;
if (cur==0)
return 0;
else
delnode=cur;
if (prev==0)
{
first=first->next;
}
else
{
prev->next=cur->next;
if (cur==last)
last=prev;
}
delete delnode;
return 1;
}
}
template <class t>
std::ostream& operator <<(std::ostream &output,llist<t> const &l)
{
typename llist<t>::nodetype *cur;
cur=l.first;
while (cur!=0)
{
output<<cur->item<<"|" ;
cur=cur->next;
}
return output;
}
template class llist<int >;
template class llist<char >;
template std::ostream& operator << (std::ostream &output, llist<int > const &l);
template std::ostream& operator << (std::ostream &output, llist<char > const &l);
any help is appreciated
Last edited on Oct 28, 2009 at 1:50pm UTC
Oct 28, 2009 at 8:48pm UTC
never mind,got it
Oct 28, 2009 at 9:12pm UTC
Just out of interest - what was the problem?
Topic archived. No new replies allowed.