-3

我已经尝试了一切,我不明白为什么它不起作用。

g++ 抛出:

Queue.H:53:错误:将“operator<<”声明为非函数

Queue.H:53:错误:预期 â;â 在â<â 标记之前

Queue.H:59:错误:预期 â;â 在“private” 之前

代码是:

#ifndef _Queue_H_
#define _Queue_H_
#include <iostream>
#include <string>
using namespace std;

template <class T, int size>

class Queue
{
public:
    Queue():_Num(0){
        T Arr=new T[size];
        for(int i=0;i<size;i++)
            Arr[i]=0;}
    ~Queue(){
        for (int i=0;i<_Num;i++)
            delete Arr_[i];
        delete [] Arr_;
    }
    bool IsEmpty() const{return !_Num ;}
    bool IsFull() const{return (_Num==size);}
    void count() const{return _Num;}
    T& Top() const {
        if(!IsEmpty())
            return Arr_[0];
        else
            throw("empty");
    }
    void operator << (const T & item ) {
        if(!IsFull()){
            Arr_[_Num+1]=item;
            _Num++;}
        else
            throw("full");}
    
    T  operator >> (T & item) {
        if(IsEmpty())
            throw("empty");
        
        item=Arr_[0];
        delete Arr_[0];
        for(int i=1;i<_Num;i++)
            Arr_[i-1]=Arr_[i];
        _Num--;
        return item;}
    
    T operator [] (const T &number){
        return (number<size) ?Arr_[number]:throw("overload");}
    
    friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){
        for(int i=0;i<a._Num;i++)
            or<<a.Arr_[i];
        return or;
    }
    
private:
    T Arr_[size];
    int _Num;
};
4

2 回答 2

3

应在外部定义友元函数,您可能会遇到诸如访问类中定义的友元函数之类的问题。您应该只在类中留下一个朋友声明并在类外定义函数。

但是您的错误来自您命名模板变量的方式。

代替

friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){

试试看

friend ostream & operator << (ostream & or ,const Queue<T,size> &a){

ps _Num-坏主意

于 2013-01-25T11:15:11.843 回答
0

如果您像我一样担心紧耦合,那么您会特别担心friend(因为这是 C++ 必须提供的最紧耦合)。也就是说,有一种观点operator<<认为它可以在类内部轻松实现,而无需任何朋友声明:

简单来说,operator<<对于 ostream 来说,仅仅是对简单打印方式的一种美化。只是因为这种美化(链接os << a << b << c...调用),操作符不能成为它应该属于的类的方法。很多人求助于该运算符的朋友声明,imo 是一种打破丑陋解决方法的封装。所以,你可以做什么?

template <class T, int size>
class Queue
{
public:
    /**
     * Here comes the method. Inside the class, were it should be, 
     * having all the access it needs. 
     * No template-specialization-friend-declaration needed.
     */
    ostream & printToStream(ostream & or) const 
    { 
        for(int i=0;i<a._Num;i++)
            or<<Arr_[i];
        return or;
    }

private:
    T Arr_[size];
    int _Num;
};

/**
 * Here comes operator<<. It is what it really is:
 * Just a beautification, nothing more, no additional functionality.
 */
template <class T, int size> 
ostream& operator<<(ostream& os, Queue<T,size> const& q)
{ return q.printToStream(os); }

看?没什么大不了的。如果您经常这样做,并且您的方法每次都调用 printToStream,您可以将其设为模板:

template <class Printable>
ostream& operator<<(ostream& os, Printable const& p)
{ return p.printToStream(os); }

如果你想变得花哨,你可以 enable_if 那个操作符只有当它有那个成员函数时。没有更多的“朋友运算符<<我该怎么做?”,只需实现printToStream,美化运算符<<已经存在。

于 2013-01-25T13:10:48.123 回答