From: "Charles Wilt" Newsgroups: comp.os.msdos.djgpp,gnu.g++.help Subject: Help, splitting class templete between *.h and *.cpp file Date: Thu, 8 Jul 1999 19:30:16 -0400 Organization: AT&T WorldNet Services Lines: 259 Message-ID: <7m3c27$rqh$1@bgtnsc02.worldnet.att.net> NNTP-Posting-Host: 12.76.104.185 X-Trace: bgtnsc02.worldnet.att.net 931476359 28497 12.76.104.185 (8 Jul 1999 23:25:59 GMT) X-Complaints-To: abuse AT worldnet DOT att DOT net NNTP-Posting-Date: 8 Jul 1999 23:25:59 GMT X-Newsreader: Microsoft Outlook Express 4.72.3110.5 X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com First off, I'm posting this in both th djgpp and gnu.c++ forums because although I'm working with djgpp right now, I'll be moving this project to a Unix box running (Solaris?) I'm trying to use some source from our class textbook for a project. Unfortuneatly, the standards for our class include not being allowed to have any implementation code in the header file it must all be in a seperate source file. And the code from the book is writen with everything in the header file. Now, the only info from the instructor was 1) compile with '-fexternal-templates' 2) add '#pragma interface' to the header file 3) add '#pragma implementation' to the source file. On my own, from the documentation, I've figured out that I also need to make sure that the template class gets instantiated in the source file with the types I'll be using in my main program. This seems to be working fine, except for a template class that has an overloaded << operator. Can someone help me with this? Here is my source file ################################################################# // file mysochain.C #pragma implementation #include #include "mysochain.h" #include "mysonode.h" #include "myxcept.h" template SortedChain::SortedChain() { first = 0; } template SortedChain::~SortedChain() {// Destructor. Delete all nodes. SortedChainNode *next; while (first) { next = first->link; delete first; first = next; } } template bool SortedChain::IsEmpty() const { return first == 0; } template int SortedChain::Length() const {// Size of list. SortedChainNode *p = first; int len = 0; while (p) { len++; p = p->link; } return len; } template bool SortedChain::Search(const K& k, E& e) const {// Put element that matches k in e. // Return false if no match. SortedChainNode *p = first; // search for match with k while (p && p->data < k) p = p->link; // verify match if (p && p->data == k) // yes, found match {e = p->data; return true;} return false; // no match } template SortedChain& SortedChain ::Delete(const K& k, E& e) {// Delete element that matches k. // Put deleted element in e. // Throw BadInput exception if no match. SortedChainNode *p = first, *tp = 0; // trail p // search for match with k while (p && p->data < k) { tp = p; p = p->link; } // verify match if (p && p->data == k) {// found a match e = p->data; // save data // remove p from chain if (tp) tp->link = p->link; else first = p->link; // p is first node delete p; return *this;} throw BadInput(); // no match } template SortedChain& SortedChain::Insert(const E& e) {// Insert e, throw an exception if no space. SortedChainNode *p = first, *tp = 0; // trail p // move tp so that e can be inserted after tp while (p && p->data < e) { tp = p; p = p->link; } // setup a new node *q for e SortedChainNode *q = new SortedChainNode; q->data = e; // insert node just after tp q->link = p; if (tp) tp->link = q; else first = q; return *this; } template SortedChain& SortedChain ::DistinctInsert(const E& e) {// Insert e only if no element with same key // currently in list. // Throw BadInput exception if duplicate. SortedChainNode *p = first, *tp = 0; // trail p // move tp so that e can be inserted after tp while (p && p->data < e) { tp = p; p = p->link; } // check if duplicate if (p && p->data == e) throw BadInput(); // not duplicate, set up node for e SortedChainNode *q = new SortedChainNode; q->data = e; // insert node just after tp q->link = p; if (tp) tp->link = q; else first = q; return *this; } template void SortedChain::Output(ostream& out) const {// Insert the chain elements into the stream out. SortedChainNode *p; for (p = first; p; p = p->link) out << p->data << " "; } // overload << template ostream& operator<<(ostream& out, const SortedChain& x) {x.Output(out); return out;} //instantiate class we will need template class SortedChain; template ostream& operator << (ostream&, const SortedChain&); ################################################################## Here is the header // file mysochain.h // sorted chain #pragma interface #ifndef SortedChain_ #define SortedChain_ #include "mysonode.h" template class SortedChain { public: // Note the following line was not in the orignal, I've added it friend ostream& operator<< (ostream& out, const SortedChain& x); SortedChain(); ~SortedChain(); bool IsEmpty() const; int Length() const; bool Search(const K& k, E& e) const; SortedChain& Delete(const K& k, E& e); SortedChain& Insert(const E& e); SortedChain& DistinctInsert(const E& e); void Output(ostream& out) const; private: SortedChainNode *first; // pointer to first node }; #endif ################################################################## Here are the errors I'm getting Compiling: wordcount.cpp wordcount.cpp(7) In file included from wordcount.cpp:7: mysochain.h(12) Warning: friend declaration `class ostream & operator <<(cla mysochain.h(12) Warning: will not be treated as a template instantiation mysochain.h(12) Warning: unless you compile with -fguiding-decls mysochain.h(12) Warning: or add <> after the function name no errors Creating: wordcount.exe Error: wordcount.o: In function `main': wordcount.cpp(38) Error: undefined reference to `operator<<(ostream &, Sorted wordcount.cpp(42) Error: undefined reference to `operator<<(ostream &, Sorted wordcount.cpp(44) Error: undefined reference to `operator<<(ostream &, Sorted wordcount.cpp(48) Error: undefined reference to `operator<<(ostream &, Sorted wordcount.cpp(52) Error: undefined reference to `operator<<(ostream &, Sorted o:wordcount.cpp(54) Error: more undefined references to `operator<<(ostream & There were some errors I've tried changing all kinds of things, either mysochain.cpp won't compile. Or I'll get a linker error like the above but it wil continue with 'Possible canidates are . . .' Thanks in advance for any help, Charles Wilt