代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <string>
using namespace std;
template<class T1, class T2> class Person;
template<class T1, class T2>void printPerson(Person<T1, T2> & p);
template<class T1, class T2>
class Person
{
friend void printPerson<>(Person<T1, T2> & p);
public:
Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
private:
T1 m_Name;
T2 m_Age;
};
template<class T1 ,class T2>
void printPerson(Person<T1, T2> & p)
{
cout << "姓名:" << p.m_Name << " 年龄: " << p.m_Age << endl;
}
void test01()
{
Person<string, int> p("Tom", 10);
printPerson(p);
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
代码解析
- 一、在类内声明友元函数的时候,
friend void printPerson (Person<T1, T2> & p);
表示这个函数至少一个普通函数,因为模板函数或者模板类都是紧跟template<class T1, class T2>
后面;所以需要让编译器强行知道这是一个模板函数的声明就需要利用空参数列表 <>
来告诉编译器 模板函数的声明,friend void printPerson<>(Person<T1, T2> & p);
-------最终答案。 - 二、接着第一个问题看,
test01
中printPerson(p);
如果普通函数和模板函数都能匹配到printPerson
函数的话是会优先调用普通函数,在没有利用空列表来声明时,把friend void printPerson (Person<T1, T2> & p);
当做普通函数调用,但是却找不到普通函数的实现,虽然printPerson
在类外实现,但是类外实现属于模板函数的实现,所以会出错。 - 三、下面为函数模板与普通函数的区别以及调用规则,第二个注释就是我们用到的。
myPrint<>(a, b);
int c = 30;
myPrint(a, b, c);
char c1 = 'c';
char d = 'd';
myPrint(c1, d);
- 四、因为
friend void printPerson<>(Person<T1, T2> & p);
类模板中成员函数 一开始不会创建出来,而是在运行时才去创建,所以在类内声明,编译器刚开始是看不到的,所以需要在外部声明一下
template<class T1, class T2> class Person;
template<class T1, class T2>void printPerson(Person<T1, T2> & p);
- 五、总结