template的友元声明-如果友元是限定版本,则必须声明友元之前声明函数原型
2011-08-27 21:57
316 查看
在做C++Primer 4th的p555习题16.39的时候,终于意识到友元声明的依赖性(P553)
最终写出来的源代码如下所示,可以看到这很多的声明:
#include<iostream>
using namespace std;
template <int tHeight, int tWidth>
class Screen;
//声明友元函数的原型,因此能够在类Screen里面声明它的限定版本,由于这俩个声明用到了Screen,导致了上两行的Screen类的声明
template <int tHeight, int tWidth>
ostream& operator<< (ostream&, const Screen<tHeight, tWidth>&);
template <int tHeight, int tWidth>
istream& operator>> (istream&, Screen<tHeight, tWidth>&);
//以下是Screen类的定义,用了两个非类类型模板形参
template <int tHeight, int tWidth>
class Screen{
public:
Screen():height(tHeight), width(tWidth){}
//以下是具体的友元声明,很明显,这里要对函数名进行限定
friend ostream&
operator<< <tHeight, tWidth>(ostream&, const Screen<tHeight, tWidth>&);
friend istream&
operator>> <tHeight, tWidth>(istream&, Screen<tHeight, tWidth>&);
private:
int height;
int width;
};
//两个友元函数的定义
template <int tHeight, int tWidth>//其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
ostream& operator<< (ostream& os, const Screen<tHeight, tWidth>& sc){
os<<"Screen: "<<sc.width<<","<<sc.height<<endl;
return os;
}
template <int tHeight, int tWidth>//其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
istream& operator>>(istream& is, Screen<tHeight, tWidth>& sc){
is>>sc.height>>sc.width;
return is;
}
int main(){
//使用过程,相当简洁
Screen<3,5> sc;
cout<<sc<<endl;
cout<<"请输入Screen:";
cin>>sc;
cout<<sc<<endl;
system("pause");
return 0;
}
注意类外面的函数原型声明预定义,和类里面的函数声明是不完全一样的。
最终写出来的源代码如下所示,可以看到这很多的声明:
#include<iostream>
using namespace std;
template <int tHeight, int tWidth>
class Screen;
//声明友元函数的原型,因此能够在类Screen里面声明它的限定版本,由于这俩个声明用到了Screen,导致了上两行的Screen类的声明
template <int tHeight, int tWidth>
ostream& operator<< (ostream&, const Screen<tHeight, tWidth>&);
template <int tHeight, int tWidth>
istream& operator>> (istream&, Screen<tHeight, tWidth>&);
//以下是Screen类的定义,用了两个非类类型模板形参
template <int tHeight, int tWidth>
class Screen{
public:
Screen():height(tHeight), width(tWidth){}
//以下是具体的友元声明,很明显,这里要对函数名进行限定
friend ostream&
operator<< <tHeight, tWidth>(ostream&, const Screen<tHeight, tWidth>&);
friend istream&
operator>> <tHeight, tWidth>(istream&, Screen<tHeight, tWidth>&);
private:
int height;
int width;
};
//两个友元函数的定义
template <int tHeight, int tWidth>//其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
ostream& operator<< (ostream& os, const Screen<tHeight, tWidth>& sc){
os<<"Screen: "<<sc.width<<","<<sc.height<<endl;
return os;
}
template <int tHeight, int tWidth>//其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
istream& operator>>(istream& is, Screen<tHeight, tWidth>& sc){
is>>sc.height>>sc.width;
return is;
}
int main(){
//使用过程,相当简洁
Screen<3,5> sc;
cout<<sc<<endl;
cout<<"请输入Screen:";
cin>>sc;
cout<<sc<<endl;
system("pause");
return 0;
}
注意类外面的函数原型声明预定义,和类里面的函数声明是不完全一样的。
相关文章推荐
- 为下面的函数原型编写函数定义: int ascii_to_integer(char *str); 这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。如果字符串参数
- C++ primer 这本书上有这么两句话“派生类虚函数调用基类版本时,必须显式使用作用域操作符。如果派生类函数忽略了这样做,则函数调用会在运行时确定并且将是一个自身调用,从而导致无穷递归。”
- 从零开始学_JavaScript_系列(20)——js系列<7>(函数原型的两种声明方式、函数的作用域)
- c++语言 友元类和友元方法 将普通函数声明为友元函数
- 如果你需要在 XHTML 中声明 DOCTYPE,必须使用到<jsp:text>动作元素
- clang编译器, __declspec(novtable)修饰的class 如果虚函数不声明为纯虚则链接失败.
- C 函数声明, 函数原型, 函数定义
- “函数声明”、“函数原型”与“函数定义”辨析
- Item 14: 如果函数不会抛出异常就把它们声明为noexcept
- 几个基本概念:成员函数,函数声明,函数原型,函数定义
- 函数原型的声明不可小视
- 【c语言】为下面的函数原型编写函数定义,这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- 数组a[N],存放了1至N-1个数,其中某个数重复一次。写一个函数,找出被重复的数字.时间复杂度必须为o(N)函数原型:
- DLINQ 使用DataContext快速构建数据访问层DAL,发现Updata采用Attach(Entity t,true)困难重重!(如果实体声明了版本成员或者没有更新检查策略,则只能将它附加为没有原始状态的已修改实体)的解决办法!
- “函数声明”、“函数原型”与“函数定义”辨析
- C专家编程—分析signal函数的原型声明{void (*signal(int sig,void (*func)(int)))(int)}(2)
- 选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。
- 【C语言】为下面的函数原型编写函数定义: int ascii_to_integer(char *str); 这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- warning: function declaration isn’t a prototype(函数声明不是原型)的解决办法
- JS:声明函数时里面的参数是不是必须写