考虑以下示例
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()
{
}
函数模板bar
,baz
并且qux
故意不实例化。
baz
由于“明显”原因无法在 GCC 和 Clang 中编译的定义-S<void>
是S
. 但是,在这种情况下哪种语言规则有效?
一方面,
S<void>
不依赖 的模板参数baz
,成员访问要求它是完整的,这就触发了 的实例化S<void>
,失败了。需要诊断。另一方面,我们有“如果不能为非实例化模板生成有效的特化,则代码格式错误”的总括规则。这使得定义
baz
不正确。但是,不需要诊断。
更具体地说,我的假设是否正确(如 #1 中所表达),即上述S<void>
来自非实例化的引用baz
需要实例化S<void>
? bar
两个编译器都乐于接受 的 定义,它不实例化,这一事实支持了这一假设S<void>
。
但是,上述编译器对qux
Clang 抱怨的处理方式不同,而 GCC 则毫无抱怨地接受它。这是其中一个编译器中的错误吗?在这种情况下是否需要诊断?还是我假设#1 在这里工作是错误的?如果#2 是诊断的基础,那么编译器之间的差异是可以接受的。