我认为显式实例化请求也会自动实例化所有基类成员,但我得到了linker error: unresolved external symbol "public: void Base<int>::foo(int)"
使用 Visual Studio 2008 或 2010 构建此代码时。
请注意,添加一个调用foo()
inside bar()
强制编译器实例化Base<int>::bar()
并且构建成功,因此编译器似乎拥有实例化所需的所有信息foo()
.
显然,显式实例化Base<int>
source.cpp 中的内容允许构建成功,但每当显式实例化派生类时都需要显式实例化任何依赖基类,这似乎很愚蠢。
这是正常的吗?我找不到有关此问题的标准的说明。
header.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
源代码.cpp
#include "header.h"
template<typename T>
void Base<T>::foo() { }
template<typename T>
void Derived<T>::bar() {
// this->foo(); // adding this forces instantiation of foo()???
}
template class Derived<int>;
main.cpp
#include "header.h"
int main() {
Derived<int> d;
d.foo(); // Linker Error: unresolved external symbol "public: void Base<int>::foo(int)"
}
Edit:
看起来标准说只有类的成员才能通过显式类实例化来实例化,因此链接器错误在我的示例中是合理的。
请注意,类的定义是类头 { 成员规范 }和“类定义中的成员规范声明了该类的完整成员集;不能在其他地方添加任何成员。”因此,成员仅位于大括号 { } 之间,并且公共基类成员不会成为派生类的成员,它们只能从派生类或派生类的对象访问。
我唯一剩下的问题是为什么标准指定类模板的显式实例化仅实例化成员而不实例化基类的成员?我的猜测是,这可以更好地控制在何处显式实例化什么。使用显式模板类实例化的人很可能将基类定义与派生类定义放在不同的文件中,并且会分别显式实例化每个文件。