1.创建一个Person类

//
// Created by Administrator on 2021/7/16.
//

#ifndef C__TEST01_PERSON_HPP
#define C__TEST01_PERSON_HPP

template<class T1, class T2>
class Person {
//友元函数声明
friend void visitInformation(Person<T1, T2> person);
public:
Person(T1 name, T2 age);
private:
T1 name;
T2 age;
};

template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) :
name(name), age(age){}

//友元函数类外实现
//在这里定义一个函数访问Person类中的私有成员
template<class T1, class T2>
void visitInformation(Person<T1, T2> person){
cout<<"name is"<<person.name<<endl;
cout<<"age is"<<person.age<<endl;
}
#endif //C__TEST01_PERSON_HPP

在main函数中:

#include <iostream>
using namespace std;

//类的友元模板
#include "Person.hpp"
int main() {
Person<string, int> p("Tom",20);
visitInformation(p);
return 0;
}

这个结果显然是错误的:

类模板的友元函数在外面创建_友元函数

2.原因

下面来分析原因:
首先观察友元函数是在类内首行声明,是全局的,是一个普通函数的声明,下方的实现是模板函数的实现,所以可以在友元函数上加<>

friend void visitInformation<>(Person<T1, T2> person);

但是还是不对的,因为这是一个模板函数声明,编译器必须提前知道这个函数,所以把模板函数定义放在代码前面。
模板函数中含有person类,所以还需要声明模板类。

3.正确代码

//
// Created by Administrator on 2021/7/16.
//
#include <iostream>
#ifndef C__TEST01_PERSON_HPP
#define C__TEST01_PERSON_HPP
//告诉下面的方法这是模板类
template<class T1, class T2>
//声明不能说加模板class Person<T1,T2>;
class Person;

//这是在Person之前定义的,所以需要声明Person
template<class T1, class T2>
void visitInformation(Person<T1, T2> person){
cout<<"name is "<<person.name<<endl;
cout<<"age is "<<person.age<<endl;
}

template<class T1, class T2>
class Person {
//模板函数必须先实现,让编译器知道是什么函数,所以把函数放在前面定义
friend void visitInformation<>(Person<T1, T2> person);
public:
Person(T1 name, T2 age);
private:
T1 name;
T2 age;
};

template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) :
name(name), age(age){}

//在这里定义一个函数访问Person类中的私有成员

#endif //C__TEST01_PERSON_HPP
#include <iostream>
using namespace std;

//类的友元模板
#include "Person.hpp"
int main() {
Person<string, int> p("Tom",20);
visitInformation(p);
return 0;
}

结果如图:
类模板的友元函数在外面创建_友元函数_02

主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈