【问题标题】:Explicit instantiation of function template using incomplete type使用不完整类型显式实例化函数模板
【发布时间】:2021-10-22 00:43:38
【问题描述】:

以下内容:

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 的专门化可能提供正确的定义,使依赖的“嵌套”格式良好.有意见吗?

【问题讨论】:

  • f&lt;char&gt; 有两个实例化点:在显式实例化定义处和 TU 末尾。根据 [temp.point]/p8,您的代码是格式错误的 NDR;两个编译器都是正确的。

标签: c++ templates


【解决方案1】:

两个编译器都是正确的。

[温度点]/p6, 8:

6 一个显式的实例化定义是一个实例化点 由显式指定的专业化或专业化 实例化。

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

f&lt;char&gt; 有两个实例化点:在显式实例化定义处和在 TU 末尾。因为这两个实例化点会产生不同的含义(因为查找S&lt;T&gt;::nested 会产生不同的结果),所以该程序是非良构 NDR。

【讨论】:

  • 使用 NDR 标准使编译器的生活变得太容易了。当然,诊断(实际上由 clang 提供)在这里非常有用。
猜你喜欢
  • 2016-05-20
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多