假设我正在为二叉树BT
创建一个类,我有一个描述树元素BE
的类,类似
template<class T> class BE {
T *data;
BE *l, *r;
public:
...
template<class U> friend class BT;
};
template<class T> class BT {
BE<T> *root;
public:
...
private:
...
};
这似乎有效;但我对下面发生的事情有疑问。
我最初试图将朋友宣布为
template<class T> friend class BT;
然而,此处似乎有必要使用U
(或T
以外的其他内容),为什么会这样?是否暗示任何特定的BT
是任何特定BE
类的朋友?
关于模板和朋友的IBM页面提供了函数但不是类的不同类型的朋友关系的示例(并且猜测语法还没有融合到解决方案上)。我更愿意了解如何使我希望定义的朋友关系类型的规范更正确。
答案 0 :(得分:93)
template<class T> class BE{
template<class T> friend class BT;
};
不允许,因为模板参数不能互相遮挡。嵌套模板必须具有不同的模板参数名称。
template<typename T>
struct foo {
template<typename U>
friend class bar;
};
这意味着bar
是foo
的朋友,无论bar
的模板参数如何。 bar<char>
,bar<int>
,bar<float>
以及任何其他bar
都是foo<char>
的朋友。
template<typename T>
struct foo {
friend class bar<T>;
};
这意味着当bar
的模板参数与foo
匹配时,bar
是foo
的朋友。只有bar<char>
才会成为foo<char>
的朋友。
在您的情况下,friend class bar<T>;
就足够了。
答案 1 :(得分:6)
为了成为另一个相同类型的结构:
#include <iostream>
template<typename T_>
struct Foo
{
// Without this next line source.value_ later would be inaccessible.
template<typename> friend struct Foo;
Foo(T_ value) : value_(value) {}
template <typename AltT>
void display(AltT &&source) const
{
std::cout << "My value is " << value_ << " and my friend's value is " << source.value_ << ".\n";
}
protected:
T_ value_;
};
int main()
{
Foo<int> foo1(5);
Foo<std::string> foo2("banana");
foo1.display(foo2);
return 0;
}
输出如下:
My value is 5 and my friend's value is banana.
在template<typename> friend struct Foo;
中,您不应在T
/ typename
之后写class
,否则会导致模板参数出现错误。
答案 2 :(得分:3)
没有必要为参数命名,以便在重构时获得更少的失败点:
template <typename _KeyT, typename _ValueT> class hash_map_iterator{
template <typename, typename, int> friend class hash_map;
...
答案 3 :(得分:-2)
在我的情况下,此解决方案正常工作:
template <typename T>
class DerivedClass1 : public BaseClass1 {
template<class T> friend class DerivedClass2;
private:
int a;
};
template <typename T>
class DerivedClass2 : public BaseClass1 {
void method() { this->i;}
};
我希望它会有所帮助。