首页 > 解决方案 > 从非实例化的上下文中引用特定的模板特化:实例化与否?

问题描述

考虑以下示例

template <typename A> struct S 
{
  A a;
  void foo() {}
};  

template <typename T> void bar()
{
  S<void> *p = 0;
}

template <typename T> void baz()
{
  S<void>{}.foo();
}

template <typename T> void qux()
{
  S<void> s{};
}

int main()
{
}

函数模板barbaz并且qux故意不实例化。

baz由于“明显”原因无法在 GCC 和 Clang 中编译的定义-S<void>S. 但是,在这种情况下哪种语言规则有效?

  1. 一方面,S<void>不依赖 的模板参数baz,成员访问要求它是完整的,这就触发了 的实例化S<void>,失败了。需要诊断。

  2. 另一方面,我们有“如果不能为非实例化模板生成有效的特化,则代码格式错误”的总括规则。这使得定义baz不正确。但是,不需要诊断。

更具体地说,我的假设是否正确(如 #1 中所表达),即上述S<void>来自非实例化的引用baz需要实例化S<void>? bar两个编译器都乐于接受 的 定义,它不实例化,这一事实支持了这一假设S<void>

但是,上述编译器对quxClang 抱怨的处理方式不同,而 GCC 则毫无抱怨地接受它。这是其中一个编译器中的错误吗?在这种情况下是否需要诊断?还是我假设#1 在这里工作是错误的?如果#2 是诊断的基础,那么编译器之间的差异是可以接受的。

标签: c++templateslanguage-lawyertemplate-specializationtemplate-instantiation

解决方案


对于bazqux,表达式包括的有效性S<void>只能通过 S 的实例化来完成。然而,编译器没有义务在任何实例化之前执行此验证[temp.res]/8

可以 在任何实例化之前检查模板的有效性。[...] 程序格式错误,无需诊断,如果:

  • 由于不依赖于模板参数的构造,紧随其定义的模板的假设实例化将是格式错误的,

推荐阅读