欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…

程序员文章站 2022-06-24 20:25:36
在c++海大本科课程设计的最后章节(模板使用 )中涉及到了在mat类模板中定义友元函数friend mat operator+(mat &m, t num);//所有元素加上同一数值;...

在c++海大本科课程设计的最后章节(模板使用 )中涉及到了在mat类模板中定义友元函数friend mat operator+(mat &m, t num);//所有元素加上同一数值;

声明在类中进行如上的声明,定义在类外进行模板函数的定义,链接报错:

error lnk2001: 无法解析的外部符号 "class mat __cdecl operator+(class mat &,double)" (??h@ya?av?$mat@n@@aav0@n@z)
1>d:\installation package\vc6cn\myprojects\overload_abstract_template\template\debug\template.exe : fatal error lnk1120: 1 个无法解析的外部命令

 

对在类模板中的友元函数operator+声明前加上一句:template< typename t> 就可以正常运行了,那么究其原因,下面对类模板的友元函数进行了总结整理:

在类模板中可以出现三种友元声明:
(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
(3)只授予对类模板或函数模板的特定实例的访问权的友元声明。

要注意的是,友元函数并非成员函数,是改变了它对类成员的访问权限。

(1)没有什么好说的,如:

template

class a{

friend void fun();

//...

};
此例中fun可访问a任意类实例中的私有和保护成员

(2)

template

class a{

template

friend void fun(t u);

//...

};

这时友元使用与类不同的模板形参,t可以是任意合法标志符,友元函数可以访问a类的任何类实例的数据,即不论a的形参是int,double或其他都可以。

(3)

template

class a{

friend void fun(t u);

//...

};

此时fun只有访问类中特定实例的数据。换句话说,此时具有相同模板实参的fun函数与a类才是友元关系。即假如调用fun时其模板实参为int,则它只具有a的访问权限。当然friend void fun(t u);中<>中的t可以是任意类型,比如int,double等

回到原问题,按(3)可改为:
template class list{
friend std::ostream& operator << (std::ostream& os,const list& slist);
//……
};

按(2)可改为:

template class list{

template
friend std::ostream& operator << (std::ostream& os,const list& slist);
//……
};
在这里其实两者实现的最终效果一样的,因为调用输出运算符时需要访问的类实例的对象是它本身,所以形参t在第一种改法中一定匹配。


  

对类建立友元函数很容易。但是迁移到模板上却容易出现让人摸不着头脑的连接错误。
层次不够,不做分析,单纯介绍两种为类模板定义友元函数的方法

  1 封闭型

C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…template<typenamet>
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…classmyclass
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…friendvoidfunction(myclass<t>&arg)
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…}
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…};

  要点:友元函数定义在模板体内。

2 开放型

C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…template<typenamet>
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…classmyclass
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…template<typenamec>
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…friendvoidfunction(myclass<c>&arg);
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…};
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…template<typenamec>
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…voidfunction(myclass<c>&arg)
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…}

  要点:模板体内要另建模板。
  
  3 告诉编译器声明的设个是模板

C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…#include
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…usingnamespacestd;
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…template<typenamet>
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…classa
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…friendostream&operator<<<t>(ostream&,consta<t>&);
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…};
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…template<typenamet>
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…ostream&operator<<(ostream&output,consta<t>&a)
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…output<<"重载成功"<<endl;
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…returnoutput;
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…}
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…intmain()
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…{
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…a<int>a;
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…cout<<a;
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…}

要点:显示地在重载的运算符或者函数后面加上模板声明< t >,告诉编译器友元函数是一个类型一致的模板。

建议:
如果希望使用函数与模板特化的类型相对应,则使用方法3(模板显示声明)
如果希望使用函数与模板特化的类型相独立,则使用方法2(二重模板)
简短的内联函数使用方法1