C++ 类模板与模板类朋友,这里到底发生了什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8967521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Class template with template class friend, what's really going on here?
提问by Michael Conlen
Let's say I'm creating a class for a binary tree, BT, and I have a class which describes an element of the tree, BE, something like
假设我正在为二叉树创建一个类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:
...
};
This appears to work; however I have questions about what's going on underneath.
这似乎有效;但是我对下面发生的事情有疑问。
I originally tried to declare the friend as
我最初试图将朋友声明为
template<class T> friend class BT;
however it appears necessary to use U(or something other than T) here, why is this? Does it imply that any particular BTis friend to any particular BEclass?
但是似乎有必要在此处使用U(或其他东西T),这是为什么呢?这是否意味着任何特定对象BT是任何特定BE类的朋友?
The IBM page on templates and friends has examples of different type of friend relationships for functions but not classes (and guessing a syntax hasn't converged on the solution yet). I would prefer to understand how to get the specifications correct for the type of friend relationship I wish to define.
IBM 模板和朋友页面上有函数而不是类的不同类型朋友关系的示例(并且猜测语法尚未收敛到解决方案上)。我更愿意了解如何为我希望定义的朋友关系类型获得正确的规范。
回答by Pubby
template<class T> class BE{
template<class T> friend class BT;
};
Is not allowed because template parameters cannot shadow each other. Nested templates must have different template parameter names.
不允许,因为模板参数不能相互遮蔽。嵌套模板必须具有不同的模板参数名称。
template<typename T>
struct foo {
template<typename U>
friend class bar;
};
This means that baris a friend of fooregardless of bar's template arguments. bar<char>, bar<int>, bar<float>, and any other barwould be friends of foo<char>.
这意味着这bar是一个朋友foo不管bar的模板参数。bar<char>, bar<int>, bar<float>, 和任何其他人bar都将成为 的朋友foo<char>。
template<typename T>
struct foo {
friend class bar<T>;
};
This means that baris a friend of foowhen bar's template argument matches foo's. Only bar<char>would be a friend of foo<char>.
这意味着它bar是foowhenbar的模板参数匹配的朋友foo。只会bar<char>是 的朋友foo<char>。
In your case, friend class bar<T>;should be sufficient.
在你的情况下,friend class bar<T>;应该足够了。
回答by user6502769
In order to befriend another same-type struct:
为了与另一个相同类型的结构成为朋友:
#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;
}
With the output as follows:
输出如下:
My value is 5 and my friend's value is banana.
In template<typename> friend struct Foo;you shouldn't write Tafter typename/classotherwise it will cause a template param shadowing error.
在template<typename> friend struct Foo;你不应该写T后typename/class否则会导致模板PARAM阴影错误。
回答by cpphilosophy
It's not necessary to name the parameters so you get fewer points of failure if refactoring:
没有必要为参数命名,因此在重构时可以减少故障点:
template <typename _KeyT, typename _ValueT> class hash_map_iterator{
template <typename, typename, int> friend class hash_map;
...
回答by GutiMac
In my case this solution works correctly:
在我的情况下,此解决方案正常工作:
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;}
};
I hope it will be helpful.
我希望它会有所帮助。

