I figured an explicit instantiation request would automatically instantiate all base class members also, but I get a linker error: unresolved external symbol "public: void Base<int>::foo(int)"
when building this code using Visual Studio 2008 or 2010.
Note that adding a call to foo()
inside bar()
forces the compiler to instantiate Base<int>::bar()
and the build succeeds, so it appears that the compiler has all the necessary information to instantiate foo()
.
Obviously, explicitly instantiating Base<int>
in source.cpp allows the build to succeed, but it seems silly to need to explicitly instantiate any dependent base classes whenever explicitly instantiating a derived class.
Is this normal? I couldn't find what the standard says regarding this issue.
header.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
source.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:
It looks like the Standard says only members of a class get instantiated by an explicit class instantiation, so the linker error is justified in my example.
Note that a class is defined by class-head { member-specification } and "The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere." So members are only between the curly braces { }, and public base class members don't become members of the derived class, they are merely accessible from the derived class or by objects of the derived class.
My only remaining question is why the Standard specifies that explicit instantiation of a class template only instantiates members and not members of base classes? My guess is that this allows greater control of what gets explicitly instantiated where. Someone that's using explicit template class instantiations would most likely have the base class definitions in a different file than the derived class definitions, and would explicitly instantiate each separately.