[Effective C++ 3rd 条款46]
有理数类class Rational是一个template<class T>,T的意思是做为表示分子和分母的数值类型.为了让它能够有相乘运算,可以写个函数
template<class T>
const Rational<T> operator*(const Rational<T> &l,const Rational<T> &r)
{ ... }
为了让它能够自动进行隐式转化,因为它有一个non-explicit的构造函数
template<class T>
class Rational
{
Rational(const T& n = 0, const T& d = 1){...}
};
所以希望这样的代码可以通过编译:
Rational<int> onehalf(1,2);
Rational<int> result=onehalf * 2;
因为那个operator*函数是一个模板函数,它并不等同于Rational<int>具现化后的那个函数,所以不能做隐式转化,实际上它不能通过参数推导.
解决方法是将该函数在template<class T>class Rational{}内申明为friend,因为在编译器看到Rational<int>的时候,就将Rational<int>具现出来,所以那个friend申明会爆光.
template<class T>
class Rational
{
...
friend const Rational<T> operator*(...);
};
然而,还是会引来连接错误,因为爆光的只是申明,对于那个外面的模板函数同样需要有机会具现,才能连接成功.最终,只能再加上内联,让函数的定义在那里爆光.
template<class T>
class Rational
{
...
friend const Rational<T> operator*(...){...}
};
记住,参数推导的时候不会做隐式参数转化.
评论