模板类朋友的类模板,这里到底发生了什么?

Mic*_*len 71 c++ templates class

假设我正在为二叉树创建一个类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:
...
};
Run Code Online (Sandbox Code Playgroud)

这似乎有效; 但我对下面发生的事情有疑问.

我最初试图宣布这位朋友为

template<class T> friend class BT;
Run Code Online (Sandbox Code Playgroud)

但是这里似乎有必要使用U(或其他东西T),为什么会这样?这是否意味着任何特定BT的朋友对任何特定的BE班级都是朋友?

在模板和朋友IBM页面有不同类型的功能,但不是类朋友关系的例子(和猜测语法没有收敛的解决方案还).我更愿意了解如何使我希望定义的朋友关系类型的规范更正确.

Pub*_*bby 99

template<class T> class BE{
  template<class T> friend class BT;
};
Run Code Online (Sandbox Code Playgroud)

是不允许的,因为模板参数不能相互遮挡.嵌套模板必须具有不同的模板参数名称.


template<typename T>
struct foo {
  template<typename U>
  friend class bar;
};
Run Code Online (Sandbox Code Playgroud)

这意味着无论模板参数如何,它bar都是朋友.,,,和任何其他会的朋友.foobarbar<char>bar<int>bar<float>barfoo<char>


template<typename T>
struct foo {
  friend class bar<T>;
};
Run Code Online (Sandbox Code Playgroud)

这意味着它bar是模板参数匹配foo时的朋友.只会是朋友.barfoobar<char>foo<char>


在你的情况下,friend class bar<T>;应该足够了.

  • 更具体一点:你必须转发声明`template <typename T>类BT;`_before_定义BE,然后使用`朋友类BT <T>;`_inside_类BE. (23认同)
  • 在我的代码朋友类BT <T>中的这个构造为朋友行错误抛出错误:'BT'不是模板,即使它稍后被声明为模板<class T> class BT {...} (2认同)
  • 因此,秘密在于我需要转发声明BT才能使用朋友类BT &lt;T&gt;;行在BE中,但不用于template &lt;class U&gt;朋友类BT;。谢谢您的帮助! (2认同)

小智 7

为了成为另一个相同类型的结构:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出如下:

My value is 5 and my friend's value is banana. 
Run Code Online (Sandbox Code Playgroud)

template<typename> friend struct Foo;你不应该写Ttypename/ class否则会导致模板PARAM阴影错误.

  • 请改善你的答案. (3认同)