C++模板实例化上下文规则疑问:foo<int,X>为何包含TU2末尾点
你对加粗规则的解读完全正确,问题核心是你没有拆分两层模板实例化的上下文继承关系:
- 第一层是
f<int>的隐式实例化:由TU4中的f(0)调用触发 - 第二层是
foo<int, X>的隐式实例化:在f<int>的实例化过程中触发,属于嵌套实例化
1. f<int>的实例化上下文构成
按照标准规则:
- 函数模板特化的实例化上下文天然包含其实例化点,
f<int>的第一个实例化点就位于TU4中f(0)调用的紧邻位置,所以这个调用点直接属于f<int>的实例化上下文。 - 其次,
f本身是定义在M1模块接口单元(也就是TU2)中的模板,而f<int>的实例化点在TU4中,不属于M1的模块单元,刚好符合你加粗的规则:需要附加M1主模块接口单元(TU2)的声明序列末尾点位到f<int>的实例化上下文中。
也就是说,f<int>的实例化上下文本身就已经包含了「TU2末尾点位」和「f(0)调用点位」两个部分。
2. foo<int, X>的实例化上下文构成
foo<int, X>是f<int>实例化过程中触发的嵌套隐式实例化,完全符合[module.context]p3的前置条件:「该模板的隐式实例化的实例化点被指定为其外围特化(即f<int>)的实例化点」。
根据规则,foo<int, X>的实例化上下文是两部分的并集:
- 第一部分:外围特化
f<int>的完整实例化上下文,也就是前面提到的两个点位 - 第二部分:
foo自身对应的附加点位:foo定义在stuff模块的接口单元(TU1)中,实例化点不在stuff模块内,所以附加TU1的末尾点位(这部分你已经理解)
三者加起来就是标准示例里列出的三个点位,完全符合规则要求。
内容的提问来源于stack exchange,提问作者xmh0511
相关产品推荐
相关产品推荐

