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)
	}
};
时间: 2024-10-11 22:55:34

Effective C++ Item 46 当需要投你非成员函数定义模板的相关文章

Effective C++ Item 46 需要类型转换时请为模板定义非成员函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当我们编写一个 class template, 而它所提供之"与此 template 相关的"函数支持"所有参数之隐式类型转换"时,请将那些函数定义为 "class template内部的 friend 函数". 示例: template<typename T> class Rational{ public: Ration

读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数

1. 问题的引入——将operator*模板化 Item 24中解释了为什么对于所有参数的隐式类型转换,只有非成员函数是合格的,并且使用了一个为Rational 类创建的operator*函数作为实例.在继续之前建议你先回顾一下这个例子,因为这个条款的讨论是对它的扩展,我们会对Item 24的实例做一些看上去无伤大雅的修改:对Rational和opeartor*同时进行模板化: 1 template<typename T> 2 class Rational { 3 public: 4 Rati

Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合

本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 但是在使用for..in循环对Object中的属性进行遍历的时候,确实是需要依赖于某种顺序的.正因为ECMAScript没有对这个顺序进行明确地规范,所以每个JavaScript执行引擎都能够根据自身的特点进行实现,那么在不同的执行环境中就不能保证for..in循环的行为一致性了. 比如,以下代码在调用report方法时的结果就是不确定的

读书笔记 effective c++ Item 30 理解内联的里里外外 (大师入场啦)

最近北京房价蹭蹭猛涨,买了房子的人心花怒放,没买的人心惊肉跳,咬牙切齿,楼主作为北漂无房一族,着实又亚历山大了一把,这些天晚上睡觉总是很难入睡,即使入睡,也是浮梦连篇,即使亚历山大,对C++的热情和追求还是不减,应该是感动了周公吧,梦境从此处开始,大师入场来给我安慰了... 11点躺在床上了,脑子里总结一下最近的工作:最近的开发用到inline函数比较多,众所周知,inline的使用是为了提高程序性能,可结果却总不尽如人意,这个捉急啊,嗯?怎么突然到了山脚下,周边树木林立,郁郁葱葱,鸟儿委婉啼叫

More Effective C++----技巧 &amp; (25)将构造函数和非成员函数虚拟化

技巧 本书涉及的大多数内容都是编程的指导准则.这些准则虽是重要的,但是程序员不能单靠准则生活.有一个很早以前的卡通片叫做"菲利猫"(Felix the Cat), 菲利猫无论何时遇到困难,它都会拿它的trick包.如果一个卡通角色都有一个trick包,那么C++程序员就更应该有了.把这一章想成你的trick包的启动器. 当设计C++软件时,总会再三地受到一些问题的困扰.你如何让构造函数和非成员函数具有虚拟函数的特点?你如何限制一个类的实例的数量?你如何防止在堆中建立对象呢?你如何又能确

Effective C++ Item 30 inline里里外外

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie Item 44 46 1.将大多数 inlining 限制在小型.被频繁调用的函数身上.这可使日后的调试过程和二进制升级更容易, 也可使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化. 2.inline是对编译器的一个申请. 隐喻方式:将函数定义于 class 定义式内, 如成员函数或 friend 函数 明确声明:在定义式前加关键字 inline 编译器会拒绝大过复杂的函数 inl

Effective C++ Item 31 降低文件间编译依存关系

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:支持"编译依存性最小化"的一般构想是:相依于声明式,不要相依于定义式. 基于此构想的两个手段是 Handle classes 和 Interface classes. 示例:相依于定义式 #include <string> #include "date.h" #include "address.h" class Perso

Effective C++ Item 3 尽可能使用const

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie const 出现在*左边指const data,出现在*右边指const pointer char greeting[] = "Hello"; char *p = greeting; //non-const pointer, non-const data const char *p = greeting; //non-const pointer, const data char

Effective C++ Item 2 尽量以const, enum, inline 替换 #define

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 尽量以const, enum,inline 替换 #define --> 宁可以编译器替换预处理器 1.对于单纯常量,最好以const 对象或enum替换#define 不要用 #define ASPECT_RATIO 1.653 而用 const doube AspectRatio = 1.653 两个使用const的特殊情况 1.指向常量char *的字符串的常量指针 const ch