C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…
在c++海大本科课程设计的最后章节(模板使用 )中涉及到了在Mat类模板中定义友元函数friend Mat<T> operator+(Mat<T> &m, T num);//所有元素加上同一数值;
声明在类中进行如上的声明,定义在类外进行模板函数的定义,链接报错:
error LNK2001: 无法解析的外部符号 "class Mat<double> __cdecl operator+(class Mat<double> &,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> 就可以正常运行了,那么究其原因,下面对类模板的友元函数进行了总结整理:(下面部分内容对http://blog.sina.com.cn/s/blog_7c2c21230100svc3.html进行了引用,同时感谢博主!)
在类模板中可以出现三种友元声明:
(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
(3)只授予对类模板或函数模板的特定实例的访问权的友元声明。
要注意的是,友元函数并非成员函数,是改变了它对类成员的访问权限。
(1)没有什么好说的,如:
template<class T>
class A{
friend void fun();
//...
};
此例中fun可访问A任意类实例中的私有和保护成员
(2)
template<class T>
class A{
template<class T>
friend void fun(T u);
//...
};
这时友元使用与类不同的模板形参,T可以是任意合法标志符,友元函数可以访问A类的任何类实例的数据,即不论A的形参是int,double或其他都可以。
(3)
template<class T>
class A{
friend void fun<T>(T u);
//...
};
此时fun只有访问类中特定实例的数据。换句话说,此时具有相同模板实参的fun函数与A类才是友元关系。即假如调用fun时其模板实参为int,则它只具有A<int>的访问权限。当然friend void fun<T>(T u);中<>中的T可以是任意类型,比如int,double等
回到原问题,按(3)可改为:
template <class T> class List{
friend std::ostream& operator << <T>(std::ostream& os,const List<T>& slist);
//……
};
按(2)可改为:
template <class T> class List{
template <class T>
friend std::ostream& operator << (std::ostream& os,const List<T>& slist);
//……
};
在这里其实两者实现的最终效果一样的,因为调用输出运算符时需要访问的类实例的对象是它本身,所以形参T在第一种改法中一定匹配。
对类建立友元函数很容易。但是迁移到模板上却容易出现让人摸不着头脑的连接错误。
层次不够,不做分析,单纯介绍两种为类模板定义友元函数的方法
1 封闭型
class MyClass
{
friend void function( MyClass< T > &arg )
{
}
};
要点:友元函数定义在模板体内。
2 开放型
class MyClass
{
template< typename C >
friend void function( MyClass< C > &arg );
};
template< typename C >
void function( MyClass< C > &arg )
{
}
要点:模板体内要另建模板。
3 告诉编译器声明的设个是模板
using namespace std;
template < typename T >
class A
{
friend ostream &operator<< < T >( ostream &, const A< T > & );
};
template < typename T >
ostream &operator<< ( ostream &output, const A< T > &a )
{
output << "重载成功" << endl;
return output;
}
int main()
{
A< int > a;
cout << a;
}
要点:显示地在重载的运算符或者函数后面加上模板声明< T >,告诉编译器友元函数是一个类型一致的模板。
建议:
如果希望使用函数与模板特化的类型相对应,则使用方法3(模板显示声明)
如果希望使用函数与模板特化的类型相独立,则使用方法2(二重模板)
简短的内联函数使用方法1
C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…相关推荐
- C++ 模板类和友元
模板类的友元分三类: 1,非模板友元. 2,约束模板友元,即友元的类型取决于类被实例化时的类型. 3,非约束模板友元,即友元的所有具体化都是类的每一个具体化的友元. 1,模板类的非模板友元函数 cou ...
- 【C++】模板类的友元函数
模板类友元函数 模板类的友元函数 参考:https://blog.csdn.net/dreamer_lhs/article/details/53580088 区分:友元是否为函数模板 非模板友元 约束 ...
- C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员
一.typename与class的异同 1.啥时候既可以使用typename,又可以使用class? 当表示模板参数的时候,二者没有区别 2.啥时候只能使用typename,不能使用class? 当模 ...
- 实验名称: 类的构造函数、析构函数和友员成员应用
实验四 (实验课时:2 实验性质:设计) 实验名称: 类的构造函数.析构函数和友员成员应用 实验目的: (1)练习类的构造函数.析构函数的定义和使用方法: (2)练习对象数组.对象指针的使用: ( ...
- “模板类与友元”那些事(C++)
2019独角兽企业重金招聘Python工程师标准>>> 模版类就是类模版实例化之后的类,友元就是一种对函数访问权限的控制,通过将函数设为友元函数让其能够访问其他外部函数不能访问的&q ...
- C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?
著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:余天升 链接:http://www.zhihu.com/question/20630104/answer/15722407 ...
- 如何写模板类?(模板类的简单例子)
本文通过c++ primer plus中的例子来学习写模板类. 1.为什么需要模板类? 为了满足代码重用的需求. 比如stack类,希望不同的类型都能用. 先看看用typedef 定义的stack类. ...
- 模板类的动态模板特化
我们知道,一个模板类在实例化时一定要指定类型.但是,在项目开发中,模板的类型不是编译时确定的,而是要在运行时才会确定.简述一下本人遇到的开发环境:我现在要实现一棵B+树,B+树中key的类型是可变的, ...
- OpenCV_Viz——OpenCV中Viz的模块编译的无法解析的外部符号BUG
写在前面 由于实验室需要,需要重新编译医学图像第三方库全家桶.这里就需要编译OpenCV,而编译后查看编译的库文件中缺少一个opencv_viz2413d.lib文件(没错,这里可以看出我使用的Ope ...
最新文章
- 【Qt】Ubuntu下Qt应用程序自启动设置
- 手机1像素线粗_豪威推出4800万像素手机传感器:1/2大底
- java cell报错_有一个小小点问题,现在我想从eclipse上读取Excel表
- rsyncd.conf 详细配置
- HDU 1754 I Hate It(线段树)
- 毕业多年,我们转变了多少?
- 小程序 graphql_GraphQL应用程序中的五个常见问题(以及如何解决)
- 洛谷3396 哈希冲突 【分块】
- Swift iOS HealthKit 使用案例: 获取体温列表 HKHealthStore
- 开年福利!微服务前后端开发手册,打造完美全栈工程师
- markdown支持的脑图工具
- JavaWeb:request.setAttribute()和session.setAttribute()的区别
- linux 查看was端口,Linux如何查看端口状态
- 【路径规划-TSP问题】基于粒子群结合蚁群算法求解旅行商问题附matlab代码
- python接口自动化-token
- 改进A星算法+dwa
- 基于springboot的药店进销存管理系统#毕业设计
- 中国外贸顺差大增主因是欧洲冬天变暖
- linux文本编辑三剑客
- C++ 生产者消费者模式的简单实现