在模板中使用不完整类型

jwe*_*rek 4 c++ templates incomplete-type

如果实例化模板时类型是完整的,那么在模板中使用不完整类型是否合法?

如下

#include <iostream>

struct bar;

template <typename T>
struct foo {

    foo(bar* b) : b(b) {
    }
    
     void frobnicate() {
          b->frobnicate();
     }

     T val_;
     bar* b;
};

struct bar {
     void frobnicate() {
          std::cout << "foo\n";
     }
};

int main() {
    bar b;
    foo<int> f(&b);
    f.frobnicate();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio 编译上述内容没有任何抱怨。GCC 发出警告invalid use of incomplete type 'struct bar'但编译。Clang 错误与member access into incomplete type 'bar'.

Hol*_*Cat 5

该代码格式错误,无需诊断。

\n
\n

[temp.res.general]/6.4

\n

可以在任何实例化之前检查模板的有效性。

\n

该程序格式错误,无需诊断,如果:
\n...
\n\xe2\x80\x94 紧随其定义的模板的假设实例将是格式错误的,因为构造不依赖于模板参数,...

\n
\n
\n

如果你绝对不能bar在模板之前定义,有一个解决方法:你可以引入对模板参数的人为依赖。

\n
template <typename T, typename, typename...>\nstruct dependent_type {using type = T;};\ntemplate <typename T, typename P0, typename ...P>\nusing dependent_type_t = typename dependent_type<T, P0, P...>::type;\n
Run Code Online (Sandbox Code Playgroud)\n

然后使用dependent_type_t<bar, T>代替bar.

\n