【发布时间】:2019-05-03 18:01:52
【问题描述】:
我发现了模板友元函数需要像这样前向声明的规则:
template<typename T>
class Rational;
template<typename T>
const Rational<T> operator* (const Rational<T>& lhs, const Rational<T>& rhs);
template<typename T>
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)
{
return Rational<T>();
}
int main(void)
{
Rational<int> r;
r = r * r;
return 0;
}
不仅仅是写作
template<typename T>
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)
{
return Rational<T>();
}
并阅读explanation 声明:
当编译器在类定义中正确地看到友元行时,就会发生障碍。那时它还不知道友元函数本身就是模板;它假定它们是非模板...
...这种假设会导致编译器生成对非模板函数的调用,但链接器会给您一个“未定义的外部”错误,因为您从未真正定义过那些非模板函数。
但在我的理解r * r 应该实例化
const Rational<int> operator* (const Rational<int>& lhs, const Rational<int>& rhs);
这和成为Rational<int>的朋友有什么不同?
编译器/链接器可以区分模板函数和非模板函数吗?
【问题讨论】: