C++中一个重载的小问题

#include<iostream>
using namespace std;
class A{
friend ostream& operator<<(ostream& in,A& c);
};

ostream& operator<<(ostream& in,A& c){
cout<<"Empty"<<endl;
}

像上面这样写的时候,编译器是不报错的。 但是当加一个摸版时(改成如下所示),就会有warning了。

#include<iostream>
using namespace std;
template<class T>
class A{
friend ostream& operator<<(ostream& in,A<T>& c);
};

template<class T>
ostream& operator<<(ostream& in,A<T>& c){
cout<<"Empty"<<endl;
}

小弟初学C++遇到这种问题,完全没招了。所以只好请网上的大虾们帮忙了;谢谢了。
后来发现下面这样是对的
#include<iostream>
using namespace std;
template<class T>
class A{
friend ostream& operator<<(ostream& out,A<T>& c){ out<<"Empty!"<<endl;return out;}
};
但是写在类外
就是说
#include<iostream>
using namespace std;
template<class T>
class A{
friend ostream& operator<<(ostream& out,A<T>& c);
};
template<class T>
ostream& operator<<(ostream& out,A<T>& c){ out<<"Empty!"<<endl;return out;}
是错的

为什么写在类内是正确的, 但是写在外部就错了呢?
还有楼下的几个大哥 非常感谢你们的建议 但是你们给的答案好像有点问题吧

第1个回答  2010-02-17
//A.hpp
#include<iostream>
using namespace std;

template<typename T> class A{
friend typename ostream& operator<< <T>(ostream& in,A<T>& c);
};

template<typename T> ostream& operator<<(ostream& in,A<T>& c){
cout<<"Empty"<<endl;
return in;
}
//main.cpp
#include "A.hpp"
int main()
{
A<int> temp;
cout<<temp;
return 1;
}
首先,不管是不是用模板,你的操作符重载都是有问题的,因为没有返回值,<<操作符重载是需要一个ostream&类型的返回值的。
其次,建议用typename替代尖括号中的class。至于为什么,以后多看看模板的书就知道了。
你的申请友元一定要让类知道这个函数需要的参数,就是<T>,还要让类知道这是一个函数模板,也就是friend后面的typename。找一些简单的模板友元对比下格式就明白了。
c++还不是很熟的情况下建议不要看模板,简单了解下就好,如果需要推荐一本书《c++ templates》很不错,全是讲模板的。
希望能帮到你。
不知道你用的什么环境,我这个代码在vs2005和vs2008下是没问题的
第2个回答  2010-02-17
问题找到了。你在一个template里面声明的friend函数也必须是一个template。可以采用这样的方法。

template<class T>
class A{
//内嵌一个template来声明friend函数模板
template<class U>
friend ostream& operator<<(ostream& out, A<U>& c);
};

template<class T>
ostream& operator<<(ostream& out, A<T>&c)
{
out<<"Empty."<<endl;
return out;
}

如果你用微软的visual c++,那么内嵌模板参数也可以用T,这样看起来更清楚一些。我用的是g++编译,内嵌模板参数不能同名,只能用U。本回答被网友采纳
第3个回答  2010-02-15
c++ 这样编辑。
& operator<<(ostream& in,A<T>& c){
using namespace std;
};
#include<iostream>

cout<<"Empty"<<endl;

C++中一个重载的小问题
cout<<temp;return 1;} 首先,不管是不是用模板,你的操作符重载都是有问题的,因为没有返回值,<<操作符重载是需要一个ostream&类型的返回值的。其次,建议用typename替代尖括号中的class。至于为什么,以后多看看模板的书就知道了。你的申请友元一定要让类知道这个函数需要的参数,就是<T>,还要让...

请教关于C++中重载的问题1
指针P声明为公有的才能访问,就按友好函数访问的权限解释,因为你在重载函数中用到了Strcmp库函数,而它并不是类String的友好函数,因此是不能访问到指针P的 include <iostream> include<string> using namespace std;class String { public:String(){p=NULL;} String(char *str);friend bool operato...

一个关于C++重载的问题
int size1;int size2;int *ptr;public:Array2(int m = 3, int n = 4) :size1(m), size2(n)\/*这里改为3×4,是因为这里你把他定为10×10了,它输出的是10×10方阵的前面3行和前面4列 因为你只输入了方阵的第一行的10位和第二行的两位,其余的都没有初始化,会变成随机数 希望对...

简单C++重载问题
因为你重写C0的虚函数数不规范,导致系统认为你写的是另一个函数,具体如下:在 C0 中为 void Set1(int i);在 C1 中为 int Set1(float i);系统判定虚函数有三个要求:1.与基类函数同名;2.有相同的参数个数及对应类型;3.有相有返回值或满足类型兼容规则的指针,引用的返回值;你写的函数只有满...

C++ <<重载问题!
\/\/把void换成ostream& };ostream& operator <<(ostream &x,Point pt) \/\/重载"<<"运算符的函数头 \/\/把void换成ostream& { x<<"("<<pt.px<<","<<pt.py<<")"<<endl; \/\/这里有错 return x;} void main(){ Point p1(1,2);cout<<p1;} 现在可以了 ...

关于C++重载的一个问题求解~~
如,C++本身支持下面的转换 char a = '0';int i = (int)a;或者写成int i = int(a);现在有了如上定义,也有类似的形式了 complex a;double i = double(a);这样可以将类complex的对象转换为double,因为上面的重载提供了这样的转换方法。

c++重载问题
问题是在你的第八行:A & operator =(A & a)解决:A & operator =(const A & a)分析如下:函数fun在return 类A时,编译器需要在主调函数里创建一个临时类常量,以便能够将它赋值给主调函数里的a1.由于在主调函数里代码是a1=fun(),等号右边是个常量(分析如前),但在等号操作符重载里你...

一个C++重载的问题
最后面那个构造函数这么改:Vector::Vector(const Vector & Vec){ Length = Vec();V = new double[ Vec.Length ];for(int i = 0 ; i < Length ; i++ )V[i] = Vec.V[i];} 另外你的operator []操作符建议写两个,分别用于const对象和非const对象:double& operator[](int n){ ...

C++重载的问题
B 友元运算符,所以不是成员函数 通过.访问的全都不是

c++重载的问题,请高手回答
前者是--号在前面,需要先减然后再把减之后的对象返回,因此直接对源对象进行操作,然后返回源对象就行了。后者是--号在后面,需要返回减之前的值,但是同时也要对源对象进行减操作,但你如果在减之前就直接返回的话,就没法进行减操作了,所以只好先创建一个跟源对象一样的对象,然后对源对象减,...

相似回答