class P
{
};
template< typename P >
class C : public P
{
public:
void f()
{
P::f();
}
};
int main() {
C<P> c1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为了防止我的问题留下任何误解的空间,这是一个代码示例.如果C是没有模板,但是从继承P直接,那么样品将无法编译,因为明确的功能f()试图呼吁基类的功能P是不存在的.
但是如果C是模板化的话,那么只有在f()实际调用时才会被拾取.
我想知道为什么会有这种差异.在这两种情况下f()都是死代码并且无论如何都会被剥离,但程序在非模板场景中是不正确的.
Bau*_*gen 19
实际上,你发布的程序并不是格式错误.而"隐式实例化" C<P> c1;实例化所有成员声明,
当在需要成员定义存在的上下文中引用特化时,隐式实例化成员的特化
[N4140,14.7.1(2)]由于你从不使用C<P>::f,因此永远不需要它的定义,因此从未实例化.
这与"显式实例化"不同
template class C<P>;
Run Code Online (Sandbox Code Playgroud)
这将实例化所有成员的定义,C<P>从而导致错误.
因为允许仅使用实际形成良好的函数是有意义的.
拿vector::push_back(const T&),这需要T是可复制的.但vector即使T是可移动的非可复制类型,您仍然可以使用大部分内容.
在模板类中,identifier P是模板参数typename,它不引用class P之前定义的.所以你不能说不P::f()存在,因为你不知道哪个类将替代参数P.
稍后,当您调用模板来声明c1变量时,不需要该函数,因此没有"死代码" - 只有一个模板,它从未扩展为实际代码.