使用不完全类型显式实例化函数模板

Liv*_*ara 5 c++ templates

下列:

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

用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.
Run Code Online (Sandbox Code Playgroud)

我认为clang是正确的,在实例化时,函数f指的是S. OTOH的不完全定义,S的后期特化可能提供正确的定义,使得依赖的'嵌套'格式良好.任何意见?

T.C*_*.C. 5

两个编译器都是正确的。

[温度点]/p6, 8:

6 显式实例化定义是显式实例化指定的一个或多个特化的实例化点。

8 函数模板的特化 [...] 在一个翻译单元内可能有多个实例化点,除了上述实例化点之外,对于在翻译单元内具有实例化点的任何此类特化,翻译单元的结尾也被认为是一个实例化点。[...] 如果两个不同的实例化点根据一个定义规则 (3.2) 赋予模板特化不同的含义,则程序格式错误,无需诊断。

有两个实例化点f<char>:在显式实例化定义处和在 TU 的末尾。因为这两个实例化点会导致不同的含义(因为查找S<T>::nested会产生不同的结果),该程序是格式错误的 NDR。