如何在另一个模板类内声明一个模板友元类?

huangapple go评论84阅读模式
英文:

How to declare a template friend class inside other template class?

问题

  • 你尝试实现双向链表。你有一个linked_list类和一个DListNode类,用作容器中元素的外壳,你更喜欢将DListNode作为class而不是struct,因为你希望节点字段在外部不可访问,但你还需要在linked_list类中访问它们,所以你选择将linked_list声明为DLinstNode的友元类以提高封装性。

  • 问题: 你按计划执行了如下操作:

template <class Dty_>
class DListNode {
public:

// ...

template <class ...> friend class linked_list; // line 168
// template <class ...> friend class linked_list<Dty_, DListNode<Dty_>, std::allocator<Dty_>>; full specialization doesn't work too

protected:
// ...
};

template <
    class Ty_,
    template <class ...> class List_node_ = DListNode,
    class Alloc_ = std::allocator<Ty_>
>
class linked_list { // line 13

// ...

};
  • 然后在第13行出现错误:“使用3个模板参数重新声明”

  • 完整的错误文本:

C:\Users\averu\github-local\base\ds\list\list.cpp:13:7: error: redeclared with 3 template parameters
   13 | class linked_list { // biderectional double linked list
      |       ^~~~~~~~~~~
In file included from C:\Users\averu\github-local\base\ds\list\iterator.cpp:2,
                 from C:\Users\averu\github-local\base\ds\list\list.cpp:1:
C:\Users\averu\github-local\base\ds\list\node.cpp:168:39: note: previous declaration 'template<class ...> class linked_list' used 1 template parameter
  168 |     template <class ...> friend class linked_list;
      |
  • 问题:
    1. 如何以正确的方式声明我计划中的内容?
    2. 是否有更好的方法?
    3. 有其他建议吗?

从上面的内容中可以看出,你尝试使用可变模板,但它不起作用。也许你需要通过using声明来正确定义linked_list类,然后如何执行这个操作?

完整代码在此

英文:
  • Hello. I'm trying to implement double linked list. I have a linked_list class and DListNode class as a shell for elements in my container and I prefer DListNode as a class rather than as a struct, because I want node fields to be inaccessible outside, but I also need to get an access to them in a linked_list class, so instead of making getters and setters I have chosen to make linked_list as a friend class for DLinstNode to improve encapsulation.

  • Problem: I did what I planned like this:

template &lt;
	class Dty_
&gt;
class DListNode {
public:

// ...

template &lt;class ...&gt; friend class linked_list; // line 168
// template &lt;class ...&gt; friend class linked_list&lt;Dty_, DListNode&lt;Dty_&gt;, std::allocator&lt;Dty_&gt;&gt;; full specialization doesn&#39;t work too

protected:
// ...
};



template &lt;
    class Ty_,
    template &lt;class ...&gt; class List_node_ = DListNode,
    class Alloc_ = std::allocator&lt;Ty_&gt;
&gt;
class linked_list { // line 13

// ...

};
  • And got an error in line 13: "redeclared with 3 template parameters"

  • The full error text:

C:\Users\averu\github-local\base\ds\list\list.cpp:13:7: error: redeclared with 3 template parameters
   13 | class linked_list { // biderectional double linked list
      |       ^~~~~~~~~~~
In file included from C:\Users\averu\github-local\base\ds\list\iterator.cpp:2,
                 from C:\Users\averu\github-local\base\ds\list\list.cpp:1:
C:\Users\averu\github-local\base\ds\list\node.cpp:168:39: note: previous declaration &#39;template&lt;class ...&gt; class linked_list&#39; used 1 template parameter
  168 |     template &lt;class ...&gt; friend class linked_list;
      |     
  • Questions:
    1. How to declare what I planned in a right way?
    2. Is there any better way to do this?
    3. Any other recommendations?

As you can see there I'm trying to use variadic template, but it doesn't work. So, perhaps I need to declare class linked_list forward via using declaration how then do it?

full code there

答案1

得分: 2

你声明的友元类使用了与“linked_list”定义不同的模板参数。你需要像这样声明它为友元:

class DListNode {
public:
    template <class, template <class...> class, class> friend class linked_list;
};

因为“linked_list”有一个类模板参数,然后是一个模板模板参数,最后是另一个类参数。

https://godbolt.org/z/hxhP396nv

英文:

You declaration of the friend class uses different template arguments than the definition of linked_list. You need to declare it as a friend like so:

class DListNode {
public:
    template &lt;class, template &lt;class...&gt; class, class&gt; friend class linked_list;
};

becaus linked_list has one class template argument, followed by a template template argument, followed by another class argument.

https://godbolt.org/z/hxhP396nv

huangapple
  • 本文由 发表于 2023年3月9日 18:36:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683419.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定