首页 > 代码库 > 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:
	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)
	}
};