[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*(...){...}}; 记住,参数推导的时候不会做隐式参数转化.

评论