Я попробовал все, я не могу понять, почему это не работает.
g ++ throw:
Очередь. H: 53: ошибка: объявление оператора<<â как нефункциональный
Очередь. H: 53: ошибка: ожидается â; â перед â<знак
Очередь. 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;
};
Функция друга должна быть определена снаружи, вы можете столкнуться с такими проблемами, как Доступ к функции друга, определенной в классе . Вы должны просто оставить объявление друга внутри класса и определить функцию вне класса.
Но ваша ошибка возникает из-за того, как вы называете переменные шаблона.
Вместо
friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){
попробуй просто
friend ostream & operator << (ostream & or ,const Queue<T,size> &a){
постскриптум _Num
— Плохая идея
Если вы беспокоитесь о тесной связи, как я, вы особенно обеспокоены friend
(потому что это самая тесная связь, которую может предложить C ++). Тем не менее, есть мнение о operator<<
это облегчает реализацию внутри класса без каких-либо объявлений друзей:
Проще говоря, operator<<
для ostream это просто украшение для простого метода печати. И это только из-за этого украшения os << a << b << c...
вызывает), что оператор не может быть методом класса, частью которого он должен быть. Так много людей прибегают к объявлению друга этого оператора, что, по их мнению, является инкапсуляцией, разрушающей уродливый обходной путь. Так что ты можешь сделать?
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); }
И если вы хотите получить фантазию, вы можете включить_если этот оператор только если он имеет эту функцию-член. Нет больше «друг оператора<< как мне сделать это снова? «, просто реализовать printToStream и оператор beautification<< уже существует.