与模板类的朋友一起创建类模板,这里到底发生了什么?


78

假设我正在为二叉树创建一个类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页面上的模板和朋友页面上,有函数类型的朋友关系类型的示例,但类却没有(并猜测语法尚未在解决方案上收敛)。我更想了解如何针对我希望定义的朋友关系类型正确获取规范。

Answers:


109
template<class T> class BE{
  template<class T> friend class BT;
};

不允许,因为模板参数不能互相屏蔽。嵌套模板必须具有不同的模板参数名称。


template<typename T>
struct foo {
  template<typename U>
  friend class bar;
};

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


template<typename T>
struct foo {
  friend class bar<T>;
};

这意味着当模板参数与匹配时,它bar是一个朋友。只会成为的朋友。foobarfoobar<char>foo<char>


就您而言,friend class bar<T>;就足够了。


2
我的代码朋友类BT <T>中的此构造引发了朋友行错误的错误:即使稍后将其声明为template <class T>类BT {...}
Michael Conlen

2
因此秘诀在于,为了使用好友类BT <T>,我需要转发声明BT;行在BE中,但不用于template <class U>朋友类BT;。谢谢您的帮助!
Michael Conlen 2012年

24
更具体地说:您必须template<typename T> class BT; BE的定义之前先进行声明,然后friend class BT<T>; BE类中使用。
Bartosz Milewski

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;
}

输出如下:

My value is 5 and my friend's value is banana. 

在/之后template<typename> friend struct Foo;不应该写T,否则会导致模板参数屏蔽错误。typenameclass


3
请改善您的答案。
swiftBoy16年

正是我想要的!;)
jihlim

3

不必命名参数,因此重构时可以减少故障点:

     template <typename _KeyT, typename _ValueT> class hash_map_iterator{
       template <typename, typename, int> friend class hash_map;
       ...

-3

就我而言,此解决方案可以正常工作:

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;}
};

希望对您有所帮助。


6
当您在遮蔽模板参数并且不使用DerivedClass2的对DerivedClass1的朋友访问权限时,该解决方案应该如何正常工作?
kornman00'2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.