类模板与友元的问题/Issue with class template and its friend method
泛型是C++的一个非常大的发明,我很喜欢这个发明。但可惜的是,泛型在各个编译器中的支持各不相同。类模板及其友元的问题应该是其中
一个。我自己没有具体看C++98这类标准,只能从网上找一些片言只字去
了解一下,希望其他同学帮我解释和补充。谢谢
首先我们来看MSDN的一个例子:
http://msdn.microsoft.com/en-us/library/f1b2td24.aspx
例一可以简化为:template<class T> class X {
template<class T>
friend void method(int t, X<T> const & x);
};
template<class T> void method(int t, X<T> const & x) { cout << "hello friend." << endl; }
int main()
{
X<int> k;
method(1, k);
return 0;
}这段代码可以很好地在Visual Studio 8中编译并运行,得到:
hello friend.
这样的结果。但在gcc4中,友元的声明就出错了。
t.cpp:7: error: declaration of 'class T'
t.cpp:6: error:shadows template parm 'class T'
好在,这里提示的出错是shadow了T这个模板名称,把第二个template<class T>改成template<class T2>,编译就顺利进行了。
例子二中揭示了另一种类模板友元的声明方式,虽然该例中要说明的是另一个问题。根据例二,上面的简化代码可以改成:template<class T> class X;
template<class T> void method(int t, X<T> const & x);
template<class T> class X {
friend void method<> (int t, X<T> const & x); //这里不需要重新写template <class T>这样的声明
};
template<class T> void method(int t, X<T> const & x) { cout << "hello friend." << endl; }
int main()
{
X<int> k;
method(1, k);
return 0;
}当然了,例二中最想说明的其实是友元的特例化,也就是:template<class T> class X {
friend void method<int> (int t, X<int> const & x); //这里把友元函数特例化成只对T==int时才成立
};如果采用这种方式,在method<T>的实现中就不能访问类X的私有成员了。
例三说明的是类模板的友元类,看起来并不复杂,就不讨论了。
我想补充的时,对于例一,还有一种内嵌的实现方式:template<class T> class X {
friend void method(int t, X<T> const & x){ cout << "hello friend." << endl; }
};用这种内嵌的方式,可以把友元的声明简化到和一般的类方法声明并不多,就是多了一个friend关键字。
然而,采用这种方式声明的友元是不可以和实现分离的。
[ 本帖最后由 key 于 17-5-2009 11:20 编辑 ]
页:
[1]