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 BT
is friend to any particular BE
class?
但是似乎有必要在此处使用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 bar
is a friend of foo
regardless of bar
's template arguments. bar<char>
, bar<int>
, bar<float>
, and any other bar
would 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 bar
is a friend of foo
when bar
's template argument matches foo
's. Only bar<char>
would be a friend of foo<char>
.
这意味着它bar
是foo
whenbar
的模板参数匹配的朋友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 T
after typename
/class
otherwise 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.
我希望它会有所帮助。