【问题标题】:Function template: point of instantiation and declaration函数模板:实例化和声明点
【发布时间】:2020-07-20 07:16:07
【问题描述】:

我对 Stroustrup C++ 第 4 版第 749-750 页的代码有疑问。此代码试图显示实例化绑定点。 Stroustrup 在这段代码之前说 “对于给定的模板参数集,每次使用模板都定义了一个实例化点。对于函数模板,该点(实例化)位于最近的全局或命名空间范围内,包含其使用,就在包含该使用的声明之后。”

void g(int);

template<typename T> 
void f(T a)
{
   g(a); // g is bound at a point of instantiation
}

void h(int i) 
{
   extern void g(double);
   f(i); 
}
// point of declaration for f<int>

关于此代码的问题:

  • 实例化点是f(i)吗?它是对给定参数集的模板的使用。如果不是,那是什么?
  • Stroustrup 认为f&lt;int&gt; 的“声明点”在h() {} 之后。声明点与实例化点不同吗?

【问题讨论】:

    标签: c++ language-lawyer


    【解决方案1】:

    以下所有标准参考均指N4659: March 2017 post-Kona working draft/C++17 DIS


    实例化点是f(i)吗?它是对给定参数集的模板的使用。如果不是,那是什么?

    不,虽然 f(i) 在本例中指代 f&lt;int&gt; 特化 以某种方式要求它存在,但特化的实例化点紧跟 @ 的定义987654329@,鉴于void h(int) 的定义是第一个涉及专业化的定义,根据[temp.point]/1

    对于函数模板特化,成员函数模板 特化,或成员函数或静态的特化 类模板的数据成员,如果特化是隐式的 实例化,因为它是从另一个模板中引用的 专业化和引用它的上下文取决于 模板参数,特化的实例化点 是封闭特化的实例化点。 否则,这种特化的实例化点紧跟在命名空间范围声明或定义之后 指专业化。


    Stroustrup 认为f&lt;int&gt; 的“声明点”在h() {} 之后。声明点与实例化点不同吗?

    是的,声明点与实例化点不同。来自[temp.inst]/4[temp.inst]/8

    [temp.inst]/4 除非函数模板特化已被显式实例化或显式特化,否则函数模板特化在需要的上下文中引用时隐式实例化要存在的函数定义。 [...]

    [temp.inst]/8 如果函数模板或成员函数模板以涉及重载决议的方式使用特化 , 特化的声明被隐式实例化 ([temp.over])。

    前者也依赖于重载决议,而函数模板可以在不涉及重载决议的情况下被实例化(例如显式实例化)。正如[temp.point]/8 所涵盖的,函数模板的特化可能在一个翻译单元内有多个实例化点,但给定特化的声明自然只会在单个翻译单元内生成一次(如上所述:首先在重载决议的上下文中使用)。

    在您的特定示例中,f(i)h 中的调用将隐式实例化f&lt;int&gt; 并导致f&lt;int&gt; 的声明,因为调用涉及重载解析,但这些机制由不同但相关的规则。

    【讨论】:

    • Stroustrup 进一步指出“f() 的实例化点在 h() 之外。这对于确保 f() 中调用的 g() 是全局 g( int) 而不是本地 g(double)。”所以 f(i) 不是实例化的点。
    • @notaorb 是的,请注意,在您发布此评论之前,我刚刚在几分钟前更新了答案。 f(i) 只是以需要它存在的方式指代特化,但实际的实例化点是在 void h(int) 的定义之后。
    • 所以f(i) 调用隐式实例化,它从模板生成代码?在h()? 之后添加了这段代码及其模板参数的声明。谢谢
    • 另外,如果f(i) 的声明在h() 之后,编译器将如何找到f(i)?再次感谢
    • @notaorb f(i) 调用不会调用隐式实例化(实例化不可调用),它导致隐式实例化f&lt;int&gt; 特化,而相关的实例化紧接在h() 的定义之后。特化的定义不是“定位”在h() 之后。特化的定义只是主模板定义的实例化,与 主模板定义的点的名称查找限制相同,正如我的回答所涵盖的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多