und*_*ind 6 c++ templates incomplete-type template-instantiation
假设我有以下代码段:
template <class T>
class Bar
{
// static_assert(sizeof(T) > 0); // (1)
public:
void method()
{
static_assert(sizeof(T) > 0); // (2)
}
};
class Foo; // (3)
template class Bar<Foo>; // (4)
class Foo{}; // (5)
Run Code Online (Sandbox Code Playgroud)
如果我们取消注释第(1)行,我们得到一个编译时错误"不完整的类型T",它似乎很清楚:class Bar实例化由(4)启动,并且在那时class Foo只是由(3)向前声明尚未由(5)定义.
但是如果第(1)行被注释掉,那么这段代码没有错误编译,它让我困惑:(4)是一个显式的模板实例化定义,它强制编译器生成void method()代码,而line(2)也应该生成同样的错误,因为定义Foo是在后面的(5)中做出的.
我想念什么,为什么代码片段中的代码会编译?
更新:代码在GCC 8.2.0和MSVC 19.16.27025.1下编译,但在Clang 7.0.0下,它给出了"不完整类型"错误.
根据标准,在隐式实例化期间,仅实例化成员函数的声明,而不是它们的定义.
[temp.inst]/2 - 类模板特化的隐式实例化导致
- 非删除类成员函数,成员类,作用域成员枚举,静态数据成员,成员模板和朋友的声明的隐式实例化,而不是定义的隐式实例化......
但它没有说明显示实例化.整个类被实例化,这意味着它实例化了定义,method()并且此时Foo并未完成.
[temp.explicit]/11 - 命名类模板特化的显式实例化定义显式实例化类模板特化,并且是仅在实例化时定义的那些成员的显式实例化定义.
clang拒绝代码.