C++ 常见问题解答 35.16
http://www.parashift.com/c++-faq-lite/template-friends.html
#include <iostream>
template<typename T>
class Foo {
public:
Foo(T const& value = T());
friend Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
friend std::ostream& operator<< (std::ostream& o, const Foo<T>& x);
private:
T value_;
};
作者声称:
'当编译器在类定义中正确地看到友元行时,就会出现障碍。那时它还不知道友元函数本身就是模板(为什么?类模板成员函数不是默认的函数模板吗?);它假设它们是这样的非模板:'
Foo<int> operator+ (const Foo<int>& lhs, const Foo<int>& rhs)
{ ... }
std::ostream& operator<< (std::ostream& o, const Foo<int>& x)
{ ... }
为什么上述非模板?这些模板不是通过 int 实例化的吗?
'当你调用 operator+ 或 operator<< 函数时,这种假设会导致编译器生成对非模板函数的调用,但链接器会给你一个“未定义的外部”错误,因为你从未真正定义过那些非模板函数. '
事实上,要让编译器将上面的内容识别为函数模板,程序员必须明确地这样做,如下所示:
template<typename T> class Foo; // pre-declare the template class itself
template<typename T> Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
template<typename T> std::ostream& operator<< (std::ostream& o, const Foo<T>& x);
谁能解释一下?我觉得这很烦人,不知道为什么编译器不只是通过将 T 替换为“int”来实例化 Foo 类的实例,然后就结束了。
谢谢。