从非实例化的上下文中引用特定的模板特化:实例化与否?

AnT*_*AnT 5 c++ templates template-specialization language-lawyer template-instantiation

请考虑以下示例

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()
{
}
Run Code Online (Sandbox Code Playgroud)

功能模板bar,bazqux故意留下非实例化.

由于baz"明显"的原因,未能在GCC和Clang中编译的定义S<void>是无效的专业化S.但是,在这种情况下,哪种语言规则正在起作用?

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

  2. 另一方面,我们有一条全面的规则:"如果没有为非实例化的模板生成有效的专业化,则代码就是格式错误".这使得baz形成不良的定义.但是,不需要诊断.

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

然而,上述编制者的处理方式不同qux--Clang抱怨,而GCC接受它没有任何投诉.这是其中一个编译器中的错误吗?在这种情况下是否需要诊断?或者我错误地假设#1在这里工作?如果#2是诊断的基础,那么编译器之间的差异是可以接受的.

Oli*_*liv 1

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

\n\n
\n

可以在任何实例化之前 检查模板的有效性。\n [...\n \xe2\x80\x89] 如果出现以下情况,则程序格式错误,无需诊断:

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