标题:可变参数模板的递归继承的困惑
取消只看楼主
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
结帖率:100%
已结贴  问题点数:20 回复次数:6 
可变参数模板的递归继承的困惑
下面图是用tuple为例子讲解可变参数模板,里面用到了递归继承。

class tuple<Head,Tail…>:private tuple<Tail…>

我的困惑是:
1、递归继承,是编译器看到了上面这个继承代码,识别出是递归继承,然后就生成了所有的类吗?
还是说要到后面初始化列表,子类调用父类构造函数的时候,才会生成当前类的父类?
2、递归继承是编译的时候生成所有类还是运行的时候才生成?

希望大佬帮忙解惑,谢谢了
搜索更多相关主题的帖子: 困惑 递归 继承 生成 可变参数 
2022-11-06 21:00
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
得分:0 
以下是引用rjsp在2022-11-6 21:23:18的发言:

首先 class tempalte 不是 class,class template 被实例化后才是 class
我不知道为什么要称它为“递归继承”,class tuple<Head,Tail...> 与 class tuple<Tail...> 是两个不同的“类”类型

编译器不知道什么叫“递归”,自然也就识别不出是不是递归。
编译器看到 class tuple<a,b,c> 继承于 class tuple<b,c>,于是就去实例化 class tuple<b,c>,实例化 class tuple<b,c> 时又看到它继承于 class tuple<c> 于是就去实例化 class tuple<c>,……,一直到 class tuple<>

C++是静态语言,不可能运行时生成任何类型。


于是就去实例化 class tuple<b,c>,实例化 class tuple<b,c>

1、这个意思是class tuple<b,c>的实例化还没结束就又去实例化 class tuple<b,c>这个类了是吗?直到遇到了class tuple<>,然后再折回来一层一层去做没有完成的实例化吗?
2、那这样继承的时候,就像例子class tuple<a,b,c> 继承于 class tuple<b,c>,这个父类是怎么能把b又单独提取出来的?就像你刚刚说的
class tuple<Head,Tail...> 与 class tuple<Tail...> 是两个不同的“类”类型,那么父类就没有把Head单列出来了。
2022-11-06 21:37
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
得分:0 
以下是引用rjsp在2022-11-6 21:54:36的发言:

不好意思,我听不懂你在问什么

1. 实例化需要依赖的项,如果没有依赖,谁先谁后都没关系,再说template一般使用二段式构造,第一段只进行语法检查;
2. 我几乎完全听不懂呀。“这个父类是怎么能把b又单独提取出来的?” --- 代码就是这样写的呀 tuple( Head v, Tail... vtail ) : m_head(v), tuple<Tail...>(vtail...)

第2个问题其实是想问, class tuple<Head,Tail...> 继承了 class tuple<Tail...>,然后那这个class tuple<Tail...>
是不是要转换成class tuple<Head,Tail...>类型,把Head单独拿出来留在本类中,然后再分出class tuple<Tail...>出去继承?

哈哈哈,这个描述起来好困难,我的语言组织能力不够用了
2022-11-06 22:07
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
得分:0 
以下是引用rjsp在2022-11-6 22:46:28的发言:

不需要呀,你对继承(不关乎template)是不是有什么误解?

之所以我那么想,是因为被继承的类里总会单独拿出一个Head类型的变量保留下来,如果不把class tuple<Tail...>变成class tuple<Head,Tail...>,
那这个Head类型变量怎么单独取到?
2022-11-06 23:17
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
得分:0 
以下是引用rjsp在2022-11-7 09:47:57的发言:

当你把 class tuple<Head,Tail...> 与 tuple<A,B,C> 给编译器去编译,那么编译器就知道 Head 是 A, Tail... 是 B,C 呀。
你想问编译原理?


图片代码是class tuple<Head,Tail...>继承了class tuple<Tail...>,编译器是自己知道这个class tuple<Tail...>
还要再继续继承下去吗?怎么不会只继承一次就停了?是不是因为父类写成class tuple<Tail...>这种可变参数模板的形式,编译器就知道
必须要继承到class tuple<>为止?
比如说tuple<A,B,C>继承了tuple<B,C>,会不会只继承这一步就不会再往上继承了?
2022-11-07 10:29
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
得分:0 
之所以问这个,是因为感觉递归的话,可以看到不同参数一直传到同个函数的过程。
上图图片这个打引号的“递归继承”,感觉继承的过程并不清晰,无法理解为什么写成那样的代码,
就能实现,一步一步一直向上继承到达class tuple<>为止?
2022-11-07 10:33
lllyyy3
Rank: 2
等 级:论坛游民
威 望:1
帖 子:24
专家分:20
注 册:2022-10-15
得分:0 
以下是引用rjsp在2022-11-7 13:18:54的发言:

题外话:C/C++语言中没有定义“递归”的概念,自然编译器也没有。(即使是常见的“递归函数”也只是人类眼中是“递归”,在编译器眼中它根本不区分是否调用的是同一个函数)

编译器看到 tuple<A,B,C> 就去找 tuple 的定义,找到 class tuple<Head,Tail...> : private tuple<Tail...>,匹配成 class tuple<A,B,C> : private tuple<B,C>
编译器看到 tuple<B,C> 就去找 tuple 的定义,找到 class tuple<Head,Tail...> : private tuple<Tail...>,匹配成 class tuple<B,C> : private tuple<C>
编译器看到 tuple<C> 就去找 tuple 的定义,找到 class tuple<Head,Tail...> : private tuple<Tail...>,匹配成 class tuple<C> : private tuple<>
编译器看到 tuple<> 就去找 tuple 的定义,找到 class tuple<>,匹配成 class tuple<>
没了,就这样结束了。

你看到编译器在不停地匹配同一个类模板,认为在递归;而编译器却不清楚这一点(主要的是不想知道,知道了也没用),它做的事很简答:遇到一个不认识的东西就去找它的适配。

懂了,原来是编译器自己会按照 tuple 的定义去匹配出来继承关系,之前一直不知道这个所以没有绕过弯来。
谢谢r老师!
2022-11-07 15:41



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-510571-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.352839 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved