一段快要编哭的模板程序
以前看Java编程思想的时候,觉得Java泛型的擦除很蛋疼,以为C++的模板要简单的多,但为何C++模板的规则比Java的泛型还要多,大神们,帮我看看下面的程序,我都快编哭了。
模拟STL的Queue,用链表的形式实现
Queue类:
- C/C++ code
#ifndef QUEUE_H#define QUEUE_H#include "QueueItem.h"template <class Type> class Queue{ template<class Type>friend std::ostream& operator<< (std::ostream&,const Queue<Type>&);public: // empty Queue Queue(): head(0), tail(0) {} // copy control to manage pointers to QueueItems in the Queue Queue(const Queue &Q): head(0), tail(0){ copy_elems(Q); } Queue& operator=(const Queue&); ~Queue(){ destory(); } // return element from head of Queue // unchecked operation:front on an empty Queue is undefined Type& front(){ return head->item; } const Type &front() const{ return head->item; } void push(const Type&); void pop(); bool empty() const{ return head == 0; }private: QueueItem<Type> *head; QueueItem<Type> *tail; // utility functions used by copy constructor,assignment,and destructor void destory(); // delete all the elements void copy_elems(const Queue&); // copy elements from parameter};#include "Queue.cpp"#endifQueue.cpp文件:template <class Type> void Queue<Type>::destory(){ while(!empty()) pop();}template <class Type> void Queue<Type>::pop(){ // pop is unchecked:Popping off an empty Queue is undefined QueueItem<Type>* p = head; // keep pointer to head so we can delete it head = head->next; // head now points to next element delete p; // delete old head element}template <class Type> void Queue<Type>::push(const Type& val){ // allocate a new QueueItem object QueueItem<Type> *pt = new QueueItem<Type>(val); // put item onto existing queue if(empty()) head = tail = pt; // the queue now has only one element else{ tail->next = pt; tail = pt; }}template<class Type> void Queue<Type>::copy_elems(const Queue& orig){ // copy elements from orig into this Queue // loop stops when pt == 0,which happens when we read orig.tail for(QueueItem<Type>* pt = orig.head; pt; pt=pt->next) push(pt->item);}template<class Type> Queue<Type>& Queue<Type>::operator =(const Queue& other){ QueueItem<Type> *p = other.head,*q; while(p){ q = new QueueItem<Type>(p->item); if(p == other.head) head = tail = q; tail->next = q; tail = q; p = p->next; } return *this;}Queue的成员函数QueueItem类:#include "Queue.h"template<class Type> class Queue;template<class Type> class QueueItem{ friend class Queue<Type>; template<class Type>friend std::ostream& operator<< (std::ostream&,const Queue<Type>&); QueueItem(const Type &t): item(t), next(0){} Type item; // value stored in this element QueueItem *next; // pointer to next element in the Queue};测试类:#include <iostream>#include <string>#include "Queue.h"using namespace std;template<class Type> ostream& operator<<(ostream& out, const Queue<Type>& q){ out << "< "; QueueItem<Type> *p; for(p = q.head; p; p = p->next) out << p->item << " "; out << ">"; return out;}int main(){ Queue<int> q; q.push(1); q.push(2); q.push(3); cout << q; cout << endl; return 0;}加了个输出Queue的模板函数出错了,把cout << q注释掉没问题,怎么调试都有问题,出错信息如下:
--------------------Configuration: 18 - Win32 Debug--------------------
Compiling...
18.cpp
C:\Documents and Settings\user\桌面\C++\18.cpp(6) : error C2065: 'out' : undeclared identifier
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(6) : error C2297: '<<' : illegal, right operand has type 'char [3]'
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(8) : error C2065: 'q' : undeclared identifier
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(8) : error C2228: left of '.head' must have class/struct/union type
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(8) : error C2248: 'next' : cannot access private member declared in class 'QueueItem<int>'
c:\documents and settings\user\桌面\c++\queueitem.h(9) : see declaration of 'next'
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(9) : error C2248: 'item' : cannot access private member declared in class 'QueueItem<int>'
c:\documents and settings\user\桌面\c++\queueitem.h(8) : see declaration of 'item'
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(9) : error C2297: '<<' : illegal, right operand has type 'char [2]'
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
C:\Documents and Settings\user\桌面\C++\18.cpp(10) : error C2297: '<<' : illegal, right operand has type 'char [2]'
C:\Documents and Settings\user\桌面\C++\18.cpp(18) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class Queue<int> &)' being compiled
执行 cl.exe 时出错.
18.obj - 1 error(s), 0 warning(s)
我擦,疯了!分数不够了,麻烦帮帮忙,崩溃了都~!
[解决办法]
楼主用的啥子编译器?
本人用vs2005没有问题!
估计你用的是6.0。