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 ...
随机推荐
- python程序展现图片
突然想写一个python程序能够显示图片的 ,展示文字的已经实现了 现在就搞一搞这个吧 相信也是很简单 首先是放一张图片在e盘下面 等会程序打包的时候将会用到 就决定是你啦 皮卡丘: 然后就写代码吧:
- oracle 自定义类型 type / create type
一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarchar2. 2.数值类型.如:int.number(p,s).integ ...
- Spring框架学习-Spring和IOC概述
一:什么是Spring框架? spring是一个分层的javase/EEfull-stack(一站式)轻量级的java开源框架.是为了解决企业开发的复杂性而创建的.框架的主要优势是分层架构,Sprin ...
- dubbo与springmvc的简单使用
什么是Dubbo? dubbo是阿里巴巴公司开源的高性能优秀服务框架,通过高性能的RPC(远程服务调用)实现服务的输入输出功能,可以与spring框架无缝整合: 传统的架构所有的模块都在一台服务器上, ...
- ValueError: multi-byte encodings are not supported
pyton解析xml时,报错 是因为编码的问题,把xml的头 <?xml version="1.0" encoding="gb2312"?> 改成 ...
- SAS进阶《深入分析SAS》之数据汇总和展现
SAS进阶<深入分析SAS>之数据汇总和展现 1. 通过Print过程制作报表 proc print <data=数据集>; run; 选项: obs=修改观测序号列标签 no ...
- 用DataReader 分页与几种传统的分页方法的比较
对于数据库的分页,目前比较传统的方法是采用分页存储过程,其实用 DataReader 也可以实现分页,不需要写存储过程,实现效率上也比几种比较流行的分页方法要略快. 在开始这个方法之前,让我们先创建一 ...
- WinRT ListView间隔变色(二)
上文说到,WinRt中,我们不能在Style的Setter使用Binding.这个问题其实从SL5之前,一直都不可以.但是,为了使用强大的Binding,人们也一直想使用各种方法来达到Binding ...
- windows 下完全卸载service
用SC Delete命令的话,如果服务名称中带空格,则请在服务名称前面用半角的双引号括起,如SC delete "Adobe LM Service",另外Services这个子键一 ...
- swift VS NSObject
Any class that does not inherit from another class is known as a base class. Swift classes do not in ...