C++ - 模板函数须要类型转换时使用友元(friend)模板函数
模板函数须要类型转换时使用友元(friend)模板函数
本文地址: http://blog.csdn.net/caroline_wendy/article/details/24357301
非模板函数參考: http://blog.csdn.net/caroline_wendy/article/details/24309293
模板函数的隐式(implicit)类型转换, 涉及到模板參数(typename)的确定问题.
从int或double类型, 无法隐式转换为模板类(template class)的类型, 由于无法确定模板參数类型(typename), 就无法确定构造函数的參数.
所以须要使模板函数, 与模板类拥有同样的參数类型(typename), 则须要成为模板类的友元(friend).
模板类的友元, 会随着类的參数实例化, 而实例化參数类型, 从一个函数模板, 生成定制的函数, 即能够通过隐式类型转换.
由于生成了定制的函数, 所以无法找到外部的模板类定义, 能够通过:
1. 直接在友元函数内部, 实现代码(inline);
2. 在友元函数内部, 实现一个模板函数, 在把模板函数在外部实现.
代码例如以下:
/*
* test.cpp
*
* Created on: 2014.04.22
* Author: Spike
*/ /*eclipse cdt, gcc 4.8.1*/ #include <iostream> template<typename T> class Rational; template<typename T>
const Rational<T> doMultiply (const Rational<T>& lhs,
const Rational<T>& rhs); //有理数
template<typename T>
class Rational {
/*friend const Rational<T> operator* (const Rational<T>& lhs,
const Rational<T>& rhs) {
return Rational<T>(lhs.numerator()*rhs.numerator(),
lhs.denominator()*rhs.denominator());
} //方法1*/
friend const Rational<T> operator* (const Rational<T>& lhs,
const Rational<T>& rhs) {
return doMultiply(lhs, rhs);
} //方法2
public:
Rational(const T& numerator = 0, const T& denominator = 1) :
m_n(numerator), m_d(denominator) {}
const T numerator() const {return m_n;};
const T denominator() const {return m_d;};
const T value() {return (m_n/m_d);}
private:
T m_n;
T m_d;
}; template<typename T>
const Rational<T> doMultiply (const Rational<T>& lhs,
const Rational<T>& rhs) {
return Rational<T>(lhs.numerator()*rhs.numerator(),
lhs.denominator()*rhs.denominator());
} int main(void) {
Rational<double> oneFourth(1, 4);
Rational<double> result;
result = oneFourth * 3.5;
result = 3.5 * oneFourth;
std::cout << "result = " << result.value() << std::endl; return 0;
}
输出:
result = 0.875
C++ - 模板函数须要类型转换时使用友元(friend)模板函数的更多相关文章
- 读书笔记_Effective_C++_条款四十六:需要类型转换时请为模板定义非成员函数
这个条款可以看成是条款24的续集,我们先简单回顾一下条款24,它说了为什么类似于operator *这样的重载运算符要定义成非成员函数(是为了保证混合乘法2*SomeRational或者SomeRat ...
- Effective C++ -----条款46:需要类型转换时请为模板定义非成员函数
当我们编写一个class template,而它所提供之“与此template相关的”函数支持“所有参数之隐式类型转换”时,请将那些函数定义为“class template内部的friend函数”.
- C++:成员运算符重载函数和友元运算符重载函数的比较
5.2.4 成员运算符重载函数和友元运算符重载函数的比较 (1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中有两个参数:对于单目运算符而言,成员运算符重载函数 ...
- C/C++(C++内存管理,内联函数,类型转换,命名空间,string类)
---恢复内容开始--- 内存管理 new/delete C语言中提供了 malloc 和 free 两个系统函数,#include "stdlib.h"库函数,完成对堆内存的申请 ...
- 类型和原生函数及类型转换(三:终结js类型转换)
Number() parseInt() parseFloat() Boolean() String() toString() 一.显式类型转换 -------Number()函数把对象的值转换为数字. ...
- 类型和原生函数及类型转换(二:终结js类型判断)
typeof instanceof isArray() Object.prototype.toString.call() DOM对象与DOM集合对象的类型判断 一.typeof typeof是一个一元 ...
- python---django中模板渲染(csrf令牌使用,自定义模板函数)
使用终端,可以更方便的去实验,但是没有提示信息: 在项目目录下: D:\MyPython\day23\HelloWorld>python manage.py shell 开始实验: >&g ...
- <C++>友元与虚函数的组合
为类重载<<与>>这两个运算符时,重载函数必须为该类的友元函数. 当友元不能被继承,故不能当作虚函数,无法使用多态. 可以用以下结构实现友元与虚函数的组合. class bas ...
- SQL Server系统函数:类型转换函数
原文:SQL Server系统函数:类型转换函数 1.基本的转化 SELECT CAST(2008 as varchar(4)) + ' year!' SELECT CONVERT(varchar(4 ...
随机推荐
- ibatis入门教程一
这几天研究ibatis玩,参考一篇贴子进行安装配置:蓝雪森林 选择这个帖子来跟随配置是因为这个帖子看着比较干净,但是我仍旧在配置得过程中出现了好几个问题,所以我决定在这个帖子的基础上将更多细节加上,做 ...
- [ USACO 2010 FEB ] Slowing Down
\(\\\) \(Description\) 给出一棵 \(N\) 个点的树和 \(N\) 头牛,每头牛都要去往一个节点,且每头牛去往的点一定互不相同. 现在按顺序让每一头牛去往自己要去的节点,定义一 ...
- 百度地图API在vue-cli中路径错误的问题
在使用百度地图的时候,需要使用自定义的icon图片,百度的案例中使用的是线上地址,但当替换为本地图片路径的时候,错误出现了 这是本地图片地址 ) // 设置覆盖物大小 ); 这里有一点需要注意,这里路 ...
- 【译】x86程序员手册26-7.5任务切换
7.5 Task Switching 任务切换 The 80386 switches execution to another task in any of four cases: 80386在以下四 ...
- QT 杂记
1.按F4切换designer和Edit视图. 2.加载同目录下的js文件: import "XXX.js" as MyJs //首字母一定要大写 3.qml 引用的js中对象.字 ...
- 数据分片存储,mycat服务器
关闭防火墙和selinux,配置yum源配置21 .22 数据库(这里以21为例)[root@host21 ~]# tar -xf mysql-5.7.17.tar[root@host21 ~]# y ...
- TWaver 3D作品Viewer查看器
为了让开发者更方便的对各类3D模型.设备.物体进行浏览和查看,我们直接封装了mono.Viewer组件.它可以直接根据给定的数据源(json.obj.url等)进行数据加载和浏览展示.对于一般的3D设 ...
- 用 Systemtap 统计 TCP 连接
转自: https://mp.weixin.qq.com/s?__biz=MzIxMjAzMDA1MQ==&mid=2648946009&idx=1&sn=3a0be2fe4f ...
- eclipse 中常用快捷键
* 字母大小写转换 ctrl+shift+x 转为大写 ctrl+shift+y 转为小写 * eclipse 自动生成对象来接收方法的返回值的快捷键 说明:光标一定要定位到要自动生成返回值对 ...
- Oracle 数据库启动与关闭 各种方式详解整理
概述 只有具备sysdba和sysoper系统特权的用户才能启动和关闭数据库. 在启动数据库之前应该启动监听程序,否则就不能利用命令方式来管理数据库,包括启动和关闭数据库. 虽然数据库正常运行,但如果 ...