以下内容:
template< typename >
struct S;
template< typename T >
S< T >& f (S< T >& s) {
const typename S< T >::nested ignore;
return s;
}
template S< char >& f (S< char >&);
template< typename >
struct S {
struct nested { };
};
用gcc编译,但不用clang编译:
$ clang -c /tmp/t.cpp
/tmp/t.cpp:6:20: error: implicit instantiation of undefined template 'S<char>'
const typename S< T >::nested ignore;
^
/tmp/t.cpp:10:21: note: in instantiation of function template specialization 'f<char>' requested here
template S< char >& f (S< char >&);
^
/tmp/t.cpp:2:8: note: template is declared here
struct S;
^
1 error generated.
我认为clang是正确的,在实例化时,函数f指的是S. OTOH的不完整定义,S的后期特化可能提供使依赖性嵌套的正确定义&# 39;良好的。有什么意见吗?
答案 0 :(得分:4)
两个编译器都是正确的。
[temp.point] / p6,8:
6显式实例化定义是实例化点 显式指定的特化或专业化 实例
8功能模板的专业化[...]可以 在翻译单元中有多个实例化点,和 除了上面描述的实例化点之外,对于任何 这种专业化有一个实例化点 翻译单位,翻译单位的结尾也被认为是 实例化点。 [...]如果有两个不同的实例化点 根据一个给出模板专业化的不同含义 定义规则(3.2),该程序是不正确的,没有诊断 必需的。
f<char>
有两个实例化点:在显式实例化定义和TU结束时。因为这两个实例化点会产生不同的含义(因为S<T>::nested
的查找会产生不同的结果),程序是不正确的NDR。