Effective C++ Item 46 当需要投你非成员函数定义模板
本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie
经验:当我们编写一个 class template, 而它所提供之"与此 template 相关的"函数支持"全部參数之隐式类型转换"时。请将那些函数定义为 "class template内部的 friend 函数"。
演示样例:
template<typename T>
class Rational{
public:
Rational(const T &numerator = 0, const T &denominator = 1) // Item 20 对于自己定义类型以passed by reference方式传递參数。这里T有可能是内置类型或自己定义类型。
const T numerator() const; //Item 28 避免返回 handles 指向对象内部成分。
const denominator() const;
};
template<typename T>
const Rational<T> operator*(const Rational<T> &lhs, const Rational<T> &rhs){...} Rational<int> oneHalf(1, 2);
Rational<int> result = oneHalf * 2; //error
解析: operator* 接受两个 Rational<T> 參数,但它没能推导出 T 是什么
operator* 的第一參数被声明为 Rational <T>。而传递给 operator* 的第一实參(oneHalf)的类型是 Rational<int>,所以T一定是 int
operator* 的第二參数被声明为 Rational <T>,而传递给 operator* 的第二实參(2)的类型是 int。编译器无法推导出 T 是什么
纠正1:将 operator*声明为Rational<T> class 的 friend函数。 能编译成功,不能链接成功
template<typename>
class Rational{
public:
friend const Rational operator*(const Rational &lhs, const Rational &rhs);
}; template<typename T>
const Rational<T> operator*(const Rational<T> &lhs, const Rational<T> &rhs){
...
}
解析:oneHalf 为 Rational<int>, 详细化出了 class Rational<int>。 也对应地详细化出了接受 Rational<int> 參数的 operator* 。使它成为一个函数而非函数模板。
但那个详细化的函数是在 Rational template 里声明的。而 Rational template 外的 operator* 并没有详细化出它的定义。
纠正2:把 operator* 函数本体合并至声明式内
template<typename>
class Rational{
public:
friend const Rational operator*(const Rational &lhs, const Rational &rhs){
return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator)
}
};
Effective C++ Item 46 当需要投你非成员函数定义模板的更多相关文章
- 读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数
1. 问题的引入——将operator*模板化 Item 24中解释了为什么对于所有参数的隐式类型转换,只有非成员函数是合格的,并且使用了一个为Rational 类创建的operator*函数作为实例 ...
- Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...
- 读书笔记 effective c++ Item 19 像设计类型(type)一样设计
1. 你需要重视类的设计 c++同其他面向对象编程语言一样,定义了一个新的类就相当于定义了一个新的类型(type),因此作为一个c++开发人员,大量时间会被花费在扩张你的类型系统上面.这意味着你不仅仅 ...
- 读书笔记 effective c++ Item 30 理解内联的里里外外 (大师入场啦)
最近北京房价蹭蹭猛涨,买了房子的人心花怒放,没买的人心惊肉跳,咬牙切齿,楼主作为北漂无房一族,着实又亚历山大了一把,这些天晚上睡觉总是很难入睡,即使入睡,也是浮梦连篇,即使亚历山大,对C++的热情和追 ...
- 读书笔记 effective c++ Item 19 像设计类型(type)一样设计类
1. 你需要重视类的设计 c++同其他面向对象编程语言一样,定义了一个新的类就相当于定义了一个新的类型(type),因此作为一个c++开发人员,大量时间会被花费在扩张你的类型系统上面.这意味着你不仅仅 ...
- 读书笔记 effective c++ Item 24 如果函数的所有参数都需要类型转换,将其声明成非成员函数
1. 将需要隐式类型转换的函数声明为成员函数会出现问题 使类支持隐式转换是一个坏的想法.当然也有例外的情况,最常见的一个例子就是数值类型.举个例子,如果你设计一个表示有理数的类,允许从整型到有理数的隐 ...
- 读书笔记 effective c++ Item 54 让你自己熟悉包括TR1在内的标准库
1. C++0x的历史渊源 C++标准——也就是定义语言的文档和程序库——在1998被批准.在2003年,一个小的“修复bug”版本被发布.然而标准委员会仍然在继续他们的工作,一个“2.0版本”的C+ ...
- Effective C++ Item 30 inline里里外外
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie Item 44 46 1.将大多数 inlining 限制在小型.被频繁调用的函数身上.这可 ...
- 读书笔记 effective c++ Item 23 宁可使用非成员非友元函数函数也不使用成员函数
1. 非成员非友元好还是成员函数好? 想象一个表示web浏览器的类.这样一个类提供了清除下载缓存,清除URL访问历史,从系统中移除所有cookies等接口: class WebBrowser { pu ...
随机推荐
- hdu1023
import java.math.BigInteger; import java.util.Scanner; public class Main { static BigInteger fac(Big ...
- hdu 1290 竭诚为杭州电礼物50周年
专门为杭州电50周年礼事 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- Java开发中的23种设计模式具体解释
public static void main(String[] args) { SendFactory factory = new SendFactory(); Sender sender = fa ...
- NSIS:使用PassDialog插件实现密码安装(卸载)功能
原文 NSIS:使用PassDialog插件实现密码安装(卸载)功能 有时,出于特殊的需求,我们要给安装或卸载程序加一个密码,只有输入了正确的密码才可以继续.比如: 下面我们使用插件来实现安装密码: ...
- 把自解压的RAR压缩包解压到指定的软件安装目录
原文 把自解压的RAR压缩包解压到指定的软件安装目录 今天千里独行同学给轻狂来信问了一个问题:如何把一个自解压的RAR压缩包解压到我们指定的软件安装目录. 其实,在NSIS中,我们可以灵活运用相关 ...
- KMP算法(转)
KMP算法 在介绍KMP算法之前,先介绍一下BF算法. 一.BF算法 BF算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个 ...
- 一个Bug的反思
对输入数据判重,使用Map,将对象作为Key,使用map的containsKey方法来着重是否是重复记录.正常的处理流程:(1)将输入的数据封装成对象(2)判重,将没有重复的数据存储到map(3)对没 ...
- Linux核心设计依据(七)系统调用
我理解的系统调用,用户进程和内核是内核提供了一个接口进行交互.除了异常和下降外.内核系统调用是唯一合法入境.像/proc还通过系统调用访问. 系统调用的意义: 让用户进程受限地訪问硬件设备 为用户空间 ...
- Swift_3_功能
import Foundation println("Hello, World!") //声明函数 不带参数 无返回值 func func1(){ } //一个函数 传入两个Str ...
- ubuntu12.04下一个samba、tftp、nfs构造
1.samba setting 1>apt-get install samba apt-get install smbfs 2>mkdir /home/linux/shar ...